递归重命名文件,同时保留下划线之前的所有字符

递归重命名文件,同时保留下划线之前的所有字符

我需要在 CentOS 7 机器上递归重命名数千个文件,当前格式为:

(32-64 alphanumerics)_various special characters.wav

简而言之,我想递归地从所有 3 层深度的文件中删除扩展_名(注意:所有扩展名都是).wav.wav

示例: 现有:

/home/user/recordings/TEST/december/157A757989F047C3AC2EC3499B4D04A5_7075276189 by [email protected] @ 8_44_52 AM.wav

/home/user/recordings/test/october/28D1E1840DE24D9DB4CF6D1A707533F6337C2DDE_2018690759 by [email protected] @ 1_26_55 PM.wav

期望:

/home/user/recordings/TEST/december/157A757989F047C3AC2EC3499B4D04A5.wav

/home/user/recordings/test/october/28D1E1840DE24D9DB4CF6D1A707533F6337C2DDE.wav

我进行了大量搜索,发现了很多修改文件名其他部分的方法,但没有保留特定字符 ( _) 和扩展名之前的所有内容。

预先感谢您的任何帮助。

答案1

您必须提取目录部分、文件名以及前面的字符第一的下划线(因为所有文件都.wav没有必要将扩展名保存在单独的变量中):

find /home/scott/ -maxdepth 4 -type f -name '*_*.wav' -exec sh -c 'h=${1%/*}
t=${1##*/}; echo mv "$1" "${h}/${t%%_*}".wav' doom {} \;

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

答案2

我进行了大量搜索,发现了很多修改文件名其他部分的方法,但没有保留特定字符 (_) 和扩展名之前的所有内容。

sed似乎可以解决问题: sed -E 's/(.*)_[0-9].* by .*(\.wav)/\1\2/'

echo "/home/user/recordings/TEST/december/157A757989F047C3AC2EC3499B4D04A5_7075276189 by [email protected] @ 8_44_52 AM.wav" | sed -E 's/(.*)_[0-9].* by .*(\.wav)/\1\2/'
/home/user/recordings/TEST/december/157A757989F047C3AC2EC3499B4D04A5.wav

对其他示例字符串进行测试:

echo "/home/user/recordings/test/october/28D1E1840DE24D9DB4CF6D1A707533F6337C2DDE_2018690759 by [email protected] @ 1_26_55 PM.wav" | sed -E 's/(.*)_[0-9].* by .*(\.wav)/\1\2/'
/home/user/recordings/test/october/28D1E1840DE24D9DB4CF6D1A707533F6337C2DDE.wav

使用时sed,您可以保存部分表情(),然后将它们放回原处\1\2

答案3

prename例如,安装任何(Perl 重命名)实现File::Rename或来自Unicode::Tussle。 (最后我看到,CentOS 没有任何 Perl 重命名,只有 util-linuxrename不能满足您的需要,但这可能在 CentOS 7 中发生了变化。)它们都有基本语法,其中有一些用于转换每个文件名的 Perl 代码。prename CODE FILENAME...CODE

find /home/user/recordings/ -type f -exec prename 's!_[^/]*(\.[^./]*)$!$1!' {} +

Perl的解释:(\.[^./]*)$匹配名称末尾的扩展名;_[^/]*匹配文件名中的所有内容,不包含从第一个下划线开始的目录部分(无斜杠)。替换为$,即第一个且唯一的括号组中的部分。

相关内容