В папке у меня есть тысяча файлов, таких как:
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...)
Я хочу сценарий удара, который переместит эти файлы на основе первого слова в имени файла (кошка, горилла, слон, и т.д.) в папки, также созданные на основе первого слова, так, чтобы:
Следующая острота должна сделать задание:
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
, это не перестанет работать, если каталог уже будет существовать.
Обновление
Для предотвращения инжекции кода в жемчуге (благодарит @geirha) используйте функцию quotemeta следующим образом:
find . -maxdepth 1 -type f -name '*.jpg' -exec perl -e '$a="\Q@ARGV"; $a =~ /(\w+)/; `mkdir -p $1 && mv $a $1`' "{}" \;
Я использовал бы для цикла для этого.
for file in ./*" "*.jpg; do
word=${file%% *}
mkdir -p "$word" &&
mv "$file" "$word"
done
можно выполнить это в интерактивной оболочке или поместить ее в сценарий. Bash очень полезен для знания, таким образом, я рекомендую изучить его путем чтения Руководство Bash , когда у Вас есть время.