BASH 使用 for、mv 和 grep 对大量文件按字母顺序排序

BASH one-line alphabetical mass file sort using for, mv, and grep

问题

我有数千个格式为 "^[[:digit:]]\{4\} - [[:alpha:]].*" 的文件,例如:7958 - a3ykof zyimeo3.txt。我试图简单地将它们按字母顺序移动到文件夹中,从连字符后的第一个字母字符开始。

我觉得我已经很接近按照我想要的方式实现它了,但是有一个(希望很简单)问题。

我先用 echo 测试了命令,以确保它获取了正确的信息。然后我尝试用 mv 真正执行它。我根据此文件列表在下面包含了一些示例:

1439 - a74389 josifj3oj.txt
3589 - Bfoei 839982 3il.txt
4719 - an38n8f n839mm20 mi02.txt
6398 - b39ji oij3o8 j2o.txt
9287 - A2984 j289jj9 oiw.txt
.... several thousand more files

例子

这有效

这列出了所有以字母 "a" 开头的文件(在开头的 4 位数字-space-连字符-space 模式之后):

for i in "$(ls | grep -i "^[[:digit:]]\{4\} - a")"; do echo "$i"; done

这失败了

这不会将所有以字母 "a" 开头的文件(在 4 位数字-space-连字符-space 模式之后)放入 "A"文件夹:

for i in "$(ls | grep -i "^[[:digit:]]\{4\} - a")"; do mv "$i" A; done

我希望第二个命令将名为“#### - a*”或“#### - A*”的每个文件移动到名为 A 的文件夹中。但它认为它是一个大文件 string/filename 加入 "\n".

这是一个示例错误消息:

mv: cannot stat '1439 - a74389 josifj3oj.txt\n9287 - A2984 j289jj9 oiw.txt\n2719 - an38n8f n839mm20 mi02.txt': No such file or directory

有人知道我错过了什么吗?

编辑

在@alvits 的回答与@chepner 和@courtlandj 的评论之间,对我来说完美无缺的是:

for directory in {A..Z}; do
    mkdir -p "$directory" &&
    find . -iregex "./[0-9]* - ${directory}.*" -exec mv -t "$directory" {} +; 
done

这是最简单的方法。

for directory in {A..Z}; do
    mkdir "$directory" &&
    find . -iregex "./[0-9]* - ${directory}.*" -exec mv "{}" "$directory" \;
done

for 循环将根据文件所属的每个目录查询文件名。

find 命令将找到文件并将它们移动到目录。

BASH 具有类似 RE 的通配符和内置的序列创建功能。您可以像这样使用它:

for i in {{A..Z},{a..z}}; do
  mkdir "${i}" && mv [0-9][0-9][0-9][0-9]" - ${i}"*" "${i}"
done

你注意到数字的四次重复,是的,它看起来比像 [0-9]{4} 这样的普通 RE 笨拙。