在 bash 中重命名文件时对文件名中的子字符串重新排序?

在 bash 中重命名文件时对文件名中的子字符串重新排序?

我有数百个文件,所有文件的名称都遵循相同的模板:

results_20210503_input003_run017_cluster003.txt

他们在 bash 中对子字符串重新排序是有效的方法吗?

results_input003_cluster003_run017_20210503.txt

我正在考虑使用cut -f$i来获取每个字段,然后使用mv来重命名文件,但这看起来很笨重。

答案1

使用珀尔的rename命令行工具(根据您的操作系统,可能称为renameperl-renameprename):

rename 's/(results)(_[0-9]{8})(.*)(\.txt)/$1$3$2$4/' results*txt

使用-n- 标志进行试运行,向您显示重命名。

怎么运行的:

  • s/A/B/- 将文件名中的模式 A 替换为模式 B
  • 括号中的模式出现时会被赋予索引号
  • 分组包括: 1) results:字面上的“结果”; 2) _[0-9]{8}: 下划线后跟 0 到 9 的 8 位数字; 3) .*.=任意字符,*=尽可能重复之前的输入,即一系列任意字符; 4)\.txt字面上的“.txt”,.需要转义,否则将是“任何字符”,如(3)
  • 根据需要对图案组重新排序,参考$<ID>

答案2

您没有提及您的操作系统,因此很难猜测您可以使用哪些工具。我发现mmv对于这样的情况最简单。它使用 shell glob 而不是正则表达式:

$ mmv -n 'results_*_*_*_*.txt' 'results_#2_#4_#3_#1.txt'
results_20210503_input003_run017_cluster003.txt -> results_input003_cluster003_run017_20210503.txt

-n当您对建议的重命名感到满意时,删除。


如果你真的必须这么做的话”在bash中“, 然后

for f in results_*.txt; do 
  IFS=_ read -a elems <<<"${f%.txt}"
  echo mv -n "$f" "results_${elems[2]}_${elems[4]}_${elems[3]}_${elems[1]}.txt"
done
mv -n results_20210503_input003_run017_cluster003.txt results_input003_cluster003_run017_20210503.txt

删除echo来实际重命名文件。

相关内容