在一个文件夹中,我有数千个文件,例如:
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”开头的文件都将移动到此文件夹中。
- 创建“elephant”文件夹,所有以elephant开头的文件都移至该文件夹。
- (等等..)
答案1
下面的一行代码应该可以完成这个工作:
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
。finally
mkdir -p $1 && mv "$a" $1
被当作系统命令使用/bin/sh
或它的等价命令来执行。请注意-p
选项mkdir
,如果目录已经存在,它不会失败。
更新
为了防止 perl 中的代码注入(感谢@盖尔哈), 使用quotemeta功能如下:
find . -maxdepth 1 -type f -name '*.jpg' -exec perl -e '$a="\Q@ARGV"; $a =~ /(\w+)/; `mkdir -p $1 && mv $a $1`' "{}" \;
答案2
我将为此使用 for 循环。
for file in ./*" "*.jpg; do
word=${file%% *}
mkdir -p "$word" &&
mv "$file" "$word"
done
您可以在交互式 shell 中运行它,也可以将其放入脚本中。了解 Bash 非常有用,因此我建议通过阅读Bash 指南当你有时间的时候。