文件名的模式替换

文件名的模式替换

我必须再次创建我的问题,因为所有找到的解决方案都不适合我的情况。处理许多填充时,我想使用一些单行实用程序,它允许在文件名中进行多次替换。这是输入文件名称的格式

1300_grid12_04_lig_cne_767_lig.dlg

这是预期的输出:

130004_lig_cne_767.dlg

因此,对于每个文件,我必须替换两种模式“网格12" 到 "_" 和 "_lig." 到 "." 手动对于填充的整体,我可以使用两个后续循环来实现它,这是处理大量填充的非常慢的方法。

# 1st loop over the files and substitute patter _grid12_ to _.
for file in ./*.dlg; do mv -v "$file" "${file/_grid12_/_}"; done
# 2nd loop these filles to substitute _lig. to .
for file in ./*.dlg; do mv -v "$file" "${file/_lig./.}"; done

我已经尝试过重命名命令,但它无法正确识别模式:

rename 's/_grid12_/_/g' *.dlg

是否可以避免循环填充以快速完成此操作?

答案1

这应该会使循环速度加快两倍,因为它将每个文件直接重命名为最终名称。

for file in ./*.dlg; do
    new=${file/_grid12_/_}
    mv -v "$file" "${new/_lig./.}"
done

您可能可以通过并行运行重命名来获得一些加速(但 IO 可能很容易成为瓶颈):

cpu_tally=$(grep -c ^processor /proc/cpuinfo)
for file in ./*.dlg; do
    new=${file/_grid12_/_}
    printf '%s\0' "$file" "${new/_lig./.}"
done  | xargs -r0 -n2 -P$cpu_tally -exec mv -v

答案2

缓慢的是mv为每个文件执行独立实用程序。您可以切换到可以内置zsh该实用程序的位置:mv

zmodload zsh/files # makes mv and a few other file manipulation utilities builtin
autoload -Uz zmv   # batch renaming tool
zmv -v '*.dlg' '${${f/_grid12_/_}/_lig./.}'

zmv与简单循环相比具有额外的功能。例如,如果发现冲突,它将在开始重命名之前中止。

简单的循环可以是:

for f (*.dlg(#qoN)) mv -vi -- ${${f/_grid12_/_}/_lig./.}

这里还添加了一个(#qoN)glob 限定符来禁用排序。

答案3

touch 1300_grid12_04_lig_cne_767_lig.dlg
# if you have few
parallel mv {} '{= s/_grid12_04//; s/_lig.dlg/.dlg/ =}' ::: *.dlg
# if you have thousands
printf "%s\0" *.dlg |
  parallel -0 mv {} '{= s/_grid12_04//; s/_lig.dlg/.dlg/ =}'
ls 1300*dlg

相关内容