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


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

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, gorilla, elephant и т. Д.) В папки, также созданные на основе первого слова, так что:

  • Создается папка «cat», и все файлы, начинающиеся с «cat», перемещаются в эту папку.
  • Создается папка «gorilla», и все файлы, начинающиеся с «gorilla», перемещаются в эту папку.
  • Создается папка «слона», и все файлы, начинающиеся со слона, перемещаются в эту папку.
  • (И так далее..)

1
2017-10-17 16:09


происхождения




ответы:


Следующее 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, это не сработает, если каталог уже существует.

enter image description here


Обновить

Чтобы предотвратить инъекцию кода в perl (спасибо @geirha), использовать QuoteMeta выполните следующие действия:

find . -maxdepth 1 -type f -name '*.jpg' -exec perl -e '$a="\Q@ARGV"; $a =~ /(\w+)/; `mkdir -p $1 && mv $a $1`' "{}" \;

7
2017-10-17 16:22



Оно работает! благодаря - user163125
«У меня есть минимальные знания в написании сценариев, так что будьте спокойны». можете ли вы объяснить ему / ей? благодаря - αғsнιη
@KasiyA: Готово, жаль, что я спешил в пятницу. - Sylvain Pineau
Я знаю, все мы не можем ответить быстро, и я не спустил вниз, но +1 Спасибо - αғsнιη
Обратите внимание, что это сбой, если имя файла содержит " кавычки. Это связано с тем, что вы вводите данные в код, чего вы обычно хотите избежать (подумайте, Bobby Tables). Хуже того, он может запускать произвольный код с помощью специально созданных имен файлов: например. если вы запустите touch 'dog ".`mktemp`.".jpg' перед тем как найти команду, mktemp будет фактически запущен. - geirha


Для этого я бы использовал цикл for.

for file in ./*" "*.jpg; do
    word=${file%% *}
    mkdir -p "$word" &&
    mv "$file" "$word"
done

Вы можете запустить это в интерактивной оболочке или поместить в скрипт. Bash очень полезно знать, поэтому я рекомендую изучить его, прочитав Руководство Bash когда у вас есть время.


3
2017-10-19 10:41