繁体   English   中英

Bash Regex重命名文件

[英]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

dodone ,它一次查看一个文件,当前文件的名称在参数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"' "{}" \;

笔记:

  • 我正在使用FreeBSD,它有-E选项告诉-regex使用ERE。 如果您使用的是较旧的操作系统,则可能需要将ERE转换为BRE。
  • ERE坚持13位数。 如果您不止一次运行转换,这可以避免anubhava对增加减少的担忧。
  • 对于参数扩展,我使用${..%..}而不是${../../} ,使得这个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM