/ usr / bin / rename:参数列表太长(批量重命名文件)

时间:2017-02-01 22:51:01

标签: bash shell find rename

我试图通过截断文件名中出现第一个空格的文件来批量重命名某些文件。我写了一个简单的脚本来重命名这样做:

for i in *.fa; do rename 's/\s.*//' *.fa; done

这在测试中效果很好,并根据需要产生以下结果:

$:~/testenv$ ls
NM_000016.5_LastMex1_4_12 23 0 1 KB882088_3062975-30.fa  NM_000016.5_PastMex1_4_12 23 0 1 KB882088_3062975-30.fa
$:~/testenv$ for i in *.fa; do rename 's/\s.*//' *.fa; done
$:~/testenv$ ls
NM_000016.5_LastMex1_4_12  NM_000016.5_PastMex1_4_12

不幸的是,我必须在很多文件上做到这一点,大约670万。这给了我以下错误:

/usr/bin/rename: Argument list too long

我已经尝试过各种我能想到的技巧,即使我发现它似乎无法拿起文件。

$:~/testenv$ ls
NM_000016.5_astMex1_4_12 23 0 1 KB882088_3062975-30.fa   NM_000016.5_PastMex1_4_12 23 0 1 KB882088_3062975-30.fa
NM_000016.5_LastMex1_4_12 23 0 1 KB882088_3062975-30.fa    
$:~/testenv$ find . -maxdepth 1 -type f -exec sh -c 'rename 's/\s.*//' *.fa' _ {} \;
find: `./NM_000016.5_PastMex1_4_12 23 0 1 KB882088_3062975-30.fa': No such file or directory
find: `./NM_000016.5_astMex1_4_12 23 0 1 KB882088_3062975-30.fa': No such file or directory

非常感谢任何协助。

1 个答案:

答案 0 :(得分:6)

你有这个错误,因为你使用*.fa而不是作为循环遍历的glob,而是将它扩展到单个rename命令的命令行,其中名称列表超出了你的操作系统的最大参数向量长度。您不会遇到以下问题:

# run rename once per *.fa file, with only one name given each run
for i in *.fa; do rename 's/\s.*//' "$i"; done

...或其效率更高的堂兄:

# only tries to rename files that actually have a space in their name
# runs "rename" only as many times as necessary -- not once per file, like the above.
find . -name '*[[:space:]]*.fa' -exec rename 's/\s.*//' {} +

也就是说,此用例根本不需要外部rename命令。

# Rename all files with a space in their name, then ending in .fa, to truncate at the space
for i in *[[:space:]]*.fa; do
  mv -- "$i" "${i%%[[:space:]]*}"
done

如果您想保留扩展名,可以改为:

for i in *[[:space:]]*.fa; do
  mv -- "$i" "${i%%[[:space:]]*}.fa"
done