如何根据文件名中的第一个单词移动文件?

use*_*125 1 command-line bash directory filename

在一个文件夹中,我有数千个文件,例如:

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...)
Run Code Online (Sandbox Code Playgroud)

我想要一个 bash 脚本,它将根据文件名(猫、大猩猩、大象等)中的第一个单词将这些文件移动到文件夹中,该文件夹也是基于第一个单词创建的,以便:

  • 'cat' 文件夹被创建,所有以 'cat' 开头的文件都被移动到这个文件夹中。
  • 'gorilla' 文件夹被创建,所有以 'gorilla' 开头的文件都被移动到这个文件夹中。
  • 'elephant' 文件夹被创建,所有以大象开头的文件都被移动到这个文件夹中。
  • (等等..)

Syl*_*eau 7

以下 oneliner 应该可以完成这项工作:

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

解释

  • find . -maxdepth 1 -type f -name '*.jpg'-type f仅在当前文件夹 ( . -maxdepth 1) 中查找扩展名为 jpg 的文件 ( )。

  • -exec将为perl每个匹配的文件调用该命令。该字符串{}由当前正在处理的文件名替换。

  • $a="{}"; 保存当前文件

  • $a =~ /(\w+)/是正则表达式测试,特殊变量$1将包含存储在$a.

  • finallymkdir -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`' "{}" \;
Run Code Online (Sandbox Code Playgroud)