AWK、SED、REGEX 重命名文件 [英] AWK, SED, REGEX to rename files
问题描述
我只是在学习使用 REGEX、AWK 和 SED.我目前有一组要重命名的文件 - 它们都位于一个目录中.
I'm only learning to use REGEX, AWK and SED. I currently have a group of files that I'd like to rename - they all sit in one directory.
命名模式是一致的,但我想重新排列文件名,格式如下:
The naming pattern is consistent, but I would like to re-arrange the filenames, here is the format:
01._HORRIBLE_HISTORIES_S2.mp4
02._HORRIBLE_HISTORIES_S2.mp4
我想将它们重命名为 HORRIBLE_HISTORIES_s01e01.mp4 - e01 是从第一列收集的.我知道我想从第一列中获取01",将其填充到一个变量中,然后将其粘贴在每个文件名中的 S2 之后,同时我想将它从文件名的开头与._",另外我想将S2"更改为s02".
I'd like to rename them to HORRIBLE_HISTORIES_s01e01.mp4 - where the e01 is gleaned from the first column. I know that I want to grab "01" from the first column, stuff it in a variable then paste it after the S2 in each filename, at the same time I want to remove it from the beginning of the filename along with the "._", additionally I want to change the "S2" to "s02".
如果有人这么好心,你能帮我用 awk/sed 写一些东西并解释程序,我可以从中学习吗?
If anyone would be so kind, could you help me write something using awk/sed and explain the procedure, that I might learn from it?
推荐答案
for f in *.mp4; do
echo mv "$f" \
"$(awk -F '[._]' '{ si = sprintf("%02s", substr($5,2));
print $3 "_" $4 "_s" si "e" $1 "." $6 }' <<<"$f")"
done
- 遍历所有
*.mp4
文件. - 将每个重命名为
awk
命令的结果,通过命令替换 ($(...)
) 提供. awk
命令通过.
或_"将输入文件名拆分为标记(这使得第一个标记可用为$1
,第二个为$2
, ...).- 首先,将_S{number}"中的数字左填充为带有
0
的 2 位数字(即,仅当数字不存在时才会添加0
't 已经有 2 个数字)并存储在变量si
(季节索引)中;如果总是在前面加上0
没问题,那么 awk 程序"可以简化为:{ print $3 "_" $4 "_s0" substr($5,2) "e" $1 "."$6 }
- 然后重新排列结果以及剩余的标记以形成所需的文件名.
- Loops over all
*.mp4
files. - Renames each to the result of the
awk
command, provided via command substitution ($(...)
). - The
awk
command splits the input filename into tokens by.
or "_" (which makes the first token available as$1
, the second as$2
, ...). - First, the number in "_S{number}" is left-padded to 2 digits with a
0
(i.e., a0
is only prepended if the number doesn't already have 2 digits) and stored in variablesi
(season index); if it's OK to always prepend0
, the awk "program" can be simplified to:{ print $3 "_" $4 "_s0" substr($5,2) "e" $1 "." $6 }
- The result, along with the remaining tokens, is then rearranged to form the desired filename.
注意 mv
之前的 echo
以允许您安全地预览结果命令 - 删除它以执行实际重命名.
Note the echo
before mv
to allow you to safely preview the resulting command - remove it to perform actual renaming.
替代方案:使用正则表达式的纯 bash
解决方案:
Alternative: a pure bash
solution using a regular expression:
for f in *.mp4; do
[[ $f =~ ^([0-9]+)\._([^.]+)_S([^.]+)\.(.+)$ ]]
echo mv "$f" \
"${BASH_REMATCH[2]}_s0${BASH_REMATCH[3]}e${BASH_REMATCH[1]}.${BASH_REMATCH[4]}"
done
- 使用 bash 的正则表达式匹配运算符
=~
和捕获组((...)
中的子字符串)来匹配每个文件名并提取子字符串兴趣. - 匹配结果存储在特殊数组变量
$BASH_REMATCH
中,元素0
包含整个匹配,1
包含匹配的内容第一个捕获组,2
第二个,依此类推. mv
命令的目标参数然后按所需顺序组装捕获组匹配项;请注意,在这种情况下,为简单起见,我将s{number}
的零填充设为无条件 -0
只是在前面添加.- Uses bash's regular-expression matching operator,
=~
, with capture groups (the substrings in(...)
) to match against each filename and extract substrings of interest. - The matching results are stored in the special array variable
$BASH_REMATCH
, with element0
containing the entire match,1
containing what matches the first capture group,2
the second, and so on. - The
mv
command's target argument then assembles the capture-group matches in the desired order; note that in this case, for simplicity, I've made the zero-padding ofs{number}
unconditional - a0
is simply prepended.
如上,您需要在 mv
之前删除 echo
才能执行实际重命名.
As above, you need to remove echo
before mv
to perform actual renaming.
这篇关于AWK、SED、REGEX 重命名文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!