[英]Bash Regex rename files
我有一堆文件只是一个unix时间。 问题是他们的文件名转到millis,扫描目录的程序希望它们在几秒钟内完成。 所以我需要重命名所有文件以删除.txt扩展名之前的最后3位数字。 IE:
1461758015598.txt - > 1461758015.txt
我是regex和bash的新手,所以我不知道该怎么做。
这是一种方式:
for f in *.txt; do
mv "$f" "${f/[0-9][0-9][0-9].txt/.txt}"
done
在do
和done
,它一次查看一个文件,当前文件的名称在参数f
。 "$f"
是该参数的值,不变。 "${f/[0-9][0-9][0-9].txt/.txt}"
是应用了替换的参数的值:将just替换为“三位数后跟.txt
” .txt
。
正如@anubhava指出的那样,如果你不止一次地运行它,它将保持文件名的数字,所以不要这样做。 你可以通过收紧glob模式使其成为幂等的。 这有点笨拙:
for f in [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].txt; do
mv "$f" "${f/[0-9][0-9][0-9].txt/.txt}"
done
因此,您可能希望使用外部工具使其更紧凑(假设目录中的任何文件名中没有空格或换行符):
for f in $(ls -1 | egrep '^[0-9]{13}\.txt$'); do
mv "$f" "${f/[0-9][0-9][0-9].txt/.txt}"
done
您可以使用while read
循环将限制减少到“无换行符”:
ls -1 | egrep '^[0-9]{13}\.txt$' | while read f; do
mv "$f" "${f/[0-9][0-9][0-9].txt/.txt}"
done
马克的答案涵盖了许多选择。
但是如果你想要一些递归的东西,我会选择像这样的基于find
的解决方案:
find -E . -regex '.*/[0-9]{13}\.txt' -exec \
sh -c 'set -; mv -v "$0" "${0%???.txt}.txt"' "{}" \;
笔记:
-E
选项告诉-regex
使用ERE。 如果您使用的是较旧的操作系统,则可能需要将ERE转换为BRE。 ${..%..}
而不是${../../}
,使得这个POSIX兼容而不是依赖于bash。 (它当然也适用于bash,它根本不需要。) find
的选项的一部分。 如果您更愿意避免使用find
但仍希望在bash中递归,则可以使用globstar
选项:
shopt -s globstar extglob
for f in **/+([0-9]).txt; do
[[ $f =~ ^[0-9]{13}\.txt$ ]] && mv -v "$f" "${f%...\.txt}.txt"
done
请注意, globstar
依赖于bash版本4。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.