Как переместить файлы на основе первого слова в имени файла?

В папке у меня есть тысячи файлов, таких как:

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, когда у вас будет время.

Другие вопросы по тегам