【问题标题】:Simple script to clean file names清理文件名的简单脚本
【发布时间】:2013-10-12 10:19:38
【问题描述】:
我遇到了以下“问题”。我有一堆名为“ThisIsAFile-BLAH.txt”的文件(如数千个),我想清理这些文件名,以便它们只被称为“ThisIsAFile.txt”,删除“-”符号之后的所有内容,包括它。
最好的方法是什么?
提前感谢您的时间和帮助。
附:
操作系统是 GNU/Linux。
附: 2
我正在尝试通过编写简单的脚本来自学如何将琐碎的任务自动化。
解决方案:
谢谢各位。我终于明白了。
rename 's/-[^-]*(?=\.\w+)$//' *.txt
再次感谢。
【问题讨论】:
标签:
regex
linux
bash
filenames
【解决方案1】:
检查man rename,看看是否支持正则表达式。如果是这样,那么简单的事情就可以做到
rename 's/-.*/.txt/' *.txt
在所有 .txt 文件名中搜索破折号,并将其替换为 .txt 之后的所有内容
【解决方案2】:
假设:
s="ThisIsAFile-BLAH.txt"
纯 BASH:
echo "${s/-*\./.}"
ThisIsAFile.txt
使用 sed:
sed 's/-.*\./\./' <<< "$s"
ThisIsAFile.txt
【解决方案3】:
使用awk可以写成
输入文件:
ThisIsAFile2-Blah.txt
ThisIsAFile3-Blah.txt
ThisIsAFile-Blah.txt
更改命令
ls *.txt|awk `s=$1` 'BEGIN{FS="-"; OFS=""} {print "mv "$s" "$1,".txt"}' |sh
同样的输出是
ThisIsAFile2.txt
ThisIsAFile3.txt
ThisIsAFile.txt
【解决方案4】:
如果您没有太多文件,可以使用 glob 循环遍历文件:
for i in *-BLAH.txt; do
mv -nv -- "$i" "${i%-BLAH.txt}.txt"
done
(注意-n 的使用以免覆盖已经存在的文件,-v 的使用如此冗长(可选)和-- 的使用以防一个文件以一个连字符,以免混淆 mv 会试图将其解释为选项)。也不是引用!
如果你有很多文件,你可以使用find,它可能比 Bash 的 globbing 更快:
find . -maxdepth 1 -name '*-BLAH.txt' -exec bash -c 'while(($#)); do mv -nv -- "$1" "${1%-BLAH.txt}"; shift; done' _ {} +
这里我使用了find 的+ 运算符,这样bash 命令就不会产生太多次。然后 bash 对 find 给出的参数进行循环。请注意使用虚拟参数_,因为以这种方式启动,Bash 将设置其位置参数从 0 开始,而不是从 1 开始。
find 方法非常好,因为您可以微调您将应用 bash 循环的文件。在 bash 循环中,您可以生成任何您喜欢的重命名方案。