Как переместить файлы на основе первого слова в имени файла?
В папке у меня есть тысячи файлов, таких как:
cat eats mouse.jpg
cat chases mouse.jpg
gorilla eats banana.jpg
gorilla is sleeping.jpg
elephant is huge.jpg
elephant has trunk.jpg
(and so on...)
Я хочу сценарий bash, который будет перемещать эти файлы на основе первого слова в имени файла (кошка, горилла, слон и т. Д.) В папки, также созданные на основе первого слова, так что:
- Папка 'cat' будет создана, и все файлы, начинающиеся с 'cat', будут перемещены в эту папку.
- Папка 'gorilla' будет создана, и все файлы, которые начинаются с 'gorilla', будут перемещены в эту папку.
- Папка 'elephant' создана, и все файлы, которые начинаются со слона, перемещаются в эту папку.
- (И так далее..)
2 ответа
Следующий oneliner должен сделать эту работу:
find . -maxdepth 1 -type f -name '*.jpg' -exec perl -e '$a="{}"; $a =~ /(\w+)/; `mkdir -p $1 && mv "$a" $1`' \;
объяснение
find . -maxdepth 1 -type f -name '*.jpg'
буду искать файлы (-type f
) только в текущей папке (. -maxdepth 1
) с расширением jpg.-exec
позвонюperl
Команда для каждого соответствия файлов. Строка{}
заменяется текущим именем обрабатываемого файла.$a="{}";
сохраняет текущий файл$a =~ /(\w+)/
это тест регулярного выражения, специальная переменная$1
будет содержать первое слово имени файла, хранящегося в$a
,в конце концов
mkdir -p $1 && mv "$a" $1
выполняется как системная команда с/bin/sh
или его эквивалент. Обратите внимание-p
вариантmkdir
, он не потерпит неудачу, если каталог уже существует.
Обновить
Чтобы предотвратить внедрение кода в perl (спасибо @ geirha), используйте функцию quotemeta следующим образом:
find . -maxdepth 1 -type f -name '*.jpg' -exec perl -e '$a="\Q@ARGV"; $a =~ /(\w+)/; `mkdir -p $1 && mv $a $1`' "{}" \;
Я бы использовал цикл for для этого.
for file in ./*" "*.jpg; do
word=${file%% *}
mkdir -p "$word" &&
mv "$file" "$word"
done
Вы можете запустить это в интерактивной оболочке или поместить в скрипт. Bash очень полезно знать, поэтому я рекомендую изучить его, прочитав Руководство по Bash, когда у вас будет время.