AWK、SED、REGEX重命名文件
我只是在学习使用正则表达式、AWK和SED。我目前有一组我想重命名的文件-它们都位于一个目录中 命名模式是一致的,但我想重新排列文件名,格式如下:AWK、SED、REGEX重命名文件,regex,sed,awk,filenames,renaming,Regex,Sed,Awk,Filenames,Renaming,我只是在学习使用正则表达式、AWK和SED。我目前有一组我想重命名的文件-它们都位于一个目录中 命名模式是一致的,但我想重新排列文件名,格式如下: 01._HORRIBLE_HISTORIES_S2.mp4 02._HORRIBLE_HISTORIES_S2.mp4 我想将它们重命名为Thorbit_HISTORIES_s01e01.mp4,其中e01是从第一列中收集的。我知道我想从第一列抓取“01”,将其填入一个变量中,然后将其粘贴到每个文件名的S2之后,同时我想将其从文件名开头连同“.”一
01._HORRIBLE_HISTORIES_S2.mp4
02._HORRIBLE_HISTORIES_S2.mp4
我想将它们重命名为Thorbit_HISTORIES_s01e01.mp4,其中e01是从第一列中收集的。我知道我想从第一列抓取“01”,将其填入一个变量中,然后将其粘贴到每个文件名的S2之后,同时我想将其从文件名开头连同“.”一起删除,此外,我还想将“S2”更改为“s02”
如果有人愿意的话,你能帮我用awk/sed写些东西,并解释一下这个过程,让我从中学习吗?将文件名字符串转换成文本文件,然后使用循环和awk重命名文件
while read oldname; do
newname=$(awk -F'.' '{ print substr($2, 2) "_e" $1 "." $3 }' <<< ${oldname} | \
awk -F'_' '{ print $1 "_s0" substr($2, 2) $3 }');
mv ${oldname} ${newname};
done<input.txt
读取oldname时;做
newname=$(awk-F.“{print substr($2,2)”_e“$1”。$3}”
- 使用bash的正则表达式匹配运算符
=~
,以及捕获组(在(…)
中的子字符串)来匹配每个文件名并提取感兴趣的子字符串
- 匹配结果存储在特殊数组变量
$BASH_REMATCH
中,元素0
包含整个匹配,1
包含与第一个捕获组匹配的内容,2
第二个捕获组,依此类推
- 然后,
mv
命令的目标参数按照所需的顺序组合捕获组匹配项;注意,在本例中,为了简单起见,我将s{number}
的零填充设置为无条件-a0
只是在前面加上了前缀
如上所述,您需要在mv
执行实际重命名之前删除echo
。您可以使用几乎纯的bash
(使用):
如果此命令的输出符合您的需要,您可以从循环中删除echo
,或者更简单地删除(如果您的上一个命令是上述命令)问题:!!| bash
根据模式重命名多个文件的常用方法是使用Perl命令。它使用Perl正则表达式,功能非常强大。使用-n-v
测试模式,而不接触文件:
$ rename -n -v 's/^(\d+)._(.+)_S2\.mp4/$2_s02e$1.mp4/' *.mp4
01._HORRIBLE_HISTORIES_S2.mp4 renamed as HORRIBLE_HISTORIES_s02e01.mp4
02._HORRIBLE_HISTORIES_S2.mp4 renamed as HORRIBLE_HISTORIES_s02e02.mp4
使用括号将字符串捕获到变量$1
(第一次捕获)、$2
(第二次捕获)等中:
^(\d+)
捕获文件名开头的数字(转换为$1)
。(.+)\u S2\.mp4
捕获.
和\u S2.mp4
之间的所有内容(放入$2
)
$2\u s02e$1.mp4
根据需要将新文件名与捕获的数据组合在一起
当您对结果满意时,从命令中删除-n
,它将真正重命名所有文件
rename
通常默认情况下在Linux上可用(包util Linux
)。这里有一个关于查找/安装正确命令的详细说明。如果您愿意使用gawk
,正则表达式匹配真的很方便。我发现这种基于管道的解决方案比担心循环构造要好一些
ls -1 | \
gawk 'match($0, /.../, a) { printf ... | "sh" } \
END { close("sh") }'
为了便于阅读,我用省略号替换了正则表达式和mv
命令
- 第1行列出了当前目录中的所有文件名,每行一个,并将其传递到gawk命令
- 第2行运行正则表达式匹配,将捕获的组分配给数组变量
a
。该操作使用printf
将其转换为所需的命令,该命令本身通过管道传输到sh
执行
- 第3行关闭了在我们开始向它输送东西时隐式打开的外壳
因此,您只需填写正则表达式和命令语法(借用)。例如(实时代码警告):
要预览该命令(正如您应该做的那样),只需从第二行中删除|“sh”
。使用AWK。使用第一、第二和第四部分重命名文件
ls | while read file; do newfile=`echo $file | awk -F . '{print $1 "." $2 "." $4}'`; echo $newfile; mv $file $newfile; done;
我假设这只适用于固定大小的字符串。如何在任意大小的字符串上用另一个扩展替换扩展?
$ rename -n -v 's/^(\d+)._(.+)_S2\.mp4/$2_s02e$1.mp4/' *.mp4
01._HORRIBLE_HISTORIES_S2.mp4 renamed as HORRIBLE_HISTORIES_s02e01.mp4
02._HORRIBLE_HISTORIES_S2.mp4 renamed as HORRIBLE_HISTORIES_s02e02.mp4
ls -1 | \
gawk 'match($0, /.../, a) { printf ... | "sh" } \
END { close("sh") }'
ls -1 | \
gawk 'match($0, /^([0-9]+)\._([^.]+)_S([^.]+)\.(.+)$/, a) { printf "mv %s %s_s0%se%s.%s\n",a[0],a[2],a[3],a[1],a[4] | "sh" } \
END { close("sh") }'
ls | while read file; do newfile=`echo $file | awk -F . '{print $1 "." $2 "." $4}'`; echo $newfile; mv $file $newfile; done;