【问题标题】:Mass renaming files in Bash在 Bash 中批量重命名文件
【发布时间】:2017-08-01 06:25:17
【问题描述】:

我在一个目录中有多个文件,格式如下,其中开始日期和.log(最后)相同,但文件名之间的文件名不同。

来自

27_07_2017file1vc001vpxd-1605.log
27_07_2017case2vc001vpxd-9169.log
27_07_2017server3vc001vpxd-4640.log
27_07_2017file24vc001vpxd-9170.log
27_07_2017files5vc001vpxd-4641.log

file1vc001vpxd-1605_27_07_2017_1.log
case2vc001vpxd-9169_27_07_2017_1.log
server3vc001vpxd-4640_27_07_2017_1.log
file24vc001vpxd-9170_27_07_2017_1.log
files5vc001vp-4641_27_07_2017_1.log

我有几个不同的文件。请将上述文件名视为 file1、file2、file3、file4、case1、case2、number1、number2...等。 “文件”一词并非在所有文件名格式中都是固定的 - 它应该重命名为 filename_date_1.log。换句话说,它应该剪切在日期之后的中间名并保留第一个和日期中间等等

请不要建议使用renamesed 命令,因为rename 在我的Linux 服务器中不起作用,并且组织不允许我使用sed

【问题讨论】:

  • 欢迎来到 Stack Overflow。请立即阅读AboutHow to Ask 页面。请注意,根本不鼓励提出“紧急帮助”的问题。您不应在描述中包含紧急或同义词。而且如果你不需要帮助你就不会问这个问题,所以在标题中请求帮助也等于重言。
  • 所有文件名的尾随_1.log 是否固定?你试过什么?您正在考虑使用哪些命令?你真的应该尽最大努力,解释为什么它不工作,它正在产生什么,以及它应该产生什么——一个 MCVE (minimal reproducible example)。
  • 为什么您的组织不允许您使用sed?它是否允许您使用 Awk、Perl、Python ……?为什么不能安装基于 Perl 的 prename 命令?为什么不首先正确生成文件名?
  • 我投票结束这个问题,因为 Stack Overflow 不是代码编写服务。

标签: bash shell


【解决方案1】:

从包含日志的目录中运行以下操作。

$(ls | sed 's/\([0-9]\{2\}_[0-9]\{2\}_[0-9]\{4\}\)\(.*\)\.log/mv & \2_\1_1.log/')

$> ls
27_07_2017file1vc001vpxd-1605.log
$> $(ls | sed 's/\([0-9]\{2\}_[0-9]\{2\}_[0-9]\{4\}\)\(.*\)\.log/mv & \2_\1_1.log/')
$> ls
file1vc001vpxd-1605_file1vc001vpxd-1605_1.log

编辑:

纯 bash 解决方案,无需使用任何外部工具。

for f in $(ls); do [[ $f =~ ([0-9]{2}_[0-9]{2}_[0-9]{4})(.*)\.log ]] && mv $f "${BASH_REMATCH[2]}_${BASH_REMATCH[1]}_1.log" ; done

它检查每个文件名是否匹配给定的正则表达式。如果匹配,则执行mv 命令。

在执行正则表达式匹配时,它会捕获两个匹配组,因为它们需要稍后使用。

([0-9]{2}_[0-9]{2}_[0-9]{4})dd_dd_dddd 格式的任何内容捕获到第一组中。 (.*) 可以捕获任何东西。

所以正则表达式([0-9]{2}_[0-9]{2}_[0-9]{4})(.*)\.log 匹配dd_dd_dddd<anything here>.log 格式的任何文件名。

【讨论】:

  • 谢谢,你能帮我用 mv 命令吗?我的组织不允许我使用 sed cmd。我已经编辑了我的问题,请看一下。是否可以从初始日期中删除日期并放在中间,然后是_,例如从 27_07_2017file1vc001vpxd-1605.log 到 27_07_17case2vc001vpxd-9169.log 它应该是 file1vc001vpxd-1605_27_07_2017_1.log case2vc001vpxd-9169_27_07_17_1.log 可能使用“mv”cmd ??
  • @Nirmal 我已经更新了答案。这仅对您的特定格式有效。请注意,我添加了“_1.log”,而不是您在示例中显示的“.log”。
  • 您可以解释一下您的代码吗?看起来它会首先在日期之后放置点。提取单词并按我的顺序放置单词..??对,如果日期格式为 27_07_17 怎么办?对于 $(ls) 中的 f;做 [[ $f =~ (.{10})(.*)\.log ]] && mv $f "${BASH_REMATCH[2]}_${BASH_REMATCH[1]}_1.log" ;完成
  • @Nirmal 更新了答案。我有点忙,这就是为什么使用快速而肮脏的正则表达式。但是我也更新了它。希望这已经足够清楚了。
  • mv的第二个参数改成${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.log
猜你喜欢
  • 2012-09-02
  • 2010-10-10
  • 2017-01-01
  • 2015-12-12
  • 2015-03-13
  • 2021-04-04
  • 1970-01-01
  • 2012-12-24
  • 2013-12-19
相关资源
最近更新 更多