如何匹配文件名中的字符串并根据字符串重命名文件?
How to match strings in file names and rename file according to string?
我有很多文件名中有匹配的字符串。
foostring.bar
barstring.bar
fuustring.bar
aha_foostring.abc
meh_barstring.abc
lol_fuustring.abc
...
我需要找到具有匹配字符串的 bar 和 abc 文件,并将 *.bar-files basename 重命名为 *.abc-files 的样子。也就是说,加一个字符串前缀。
我正在寻找的结果应该是这样的:
aha_foostring.bar
meh_barstring.bar
lol_fuustring.bar
aha_foostring.abc
meh_barstring.abc
lol_fuustring.abc
...
澄清编辑:*.abc 文件中的字符串始终位于最后一个下划线 _
之后和点 .
之前 字符串只包含字母和数字。前缀可以包含任意数量的字符和任意类型的字符,包括 _
和 .
这意味着我还需要考虑以下示例。
dindongstring.bar
w_h.a.t_e_v_e.r_dingdongstring.abc
我一直在试验查找、前缀和基本名称,但我需要这里的帮助和建议。
谢谢
我会选择这样的东西:
(我相信有更优雅的方法来做到这一点(awk/sed))
#!/bin/bash
for filename in *.abc
do
prefix=${filename%_*}
searchstring=${filename%.abc}
searchstring=${searchstring#*_}
if [[ -f "$searchstring.bar" ]]
then
mv "${searchstring}.bar" "${prefix}_${searchstring}.bar"
fi
done
# show the result
ls -al
很抱歉在您的答案中添加了这个,但是因为我已经删除了我的答案并且您的答案最接近 OP 的需要。 (我不介意...我关心解决方案=)
编辑: 可能这就是 OP 想要的:
for f in *.abc; do
prefix=${f%_*}
bar=${f%.abc}
bar="${bar##*_}.bar"
[[ -f "$bar" ]] && mv "$bar" "${prefix}_${bar}"
done
我建议尝试以下 "magick":
$ join -j 2 <(ls -1 . | sed -n '/\.bar/s/^\(.*\)\(\.[^.]\+\)$/\t/p' | sort -k2) <(ls -1 . | sed -n '/\.abc/s/^\(.\+_\)\?\([a-zA-Z0-9]\+\)\(\.[^.]\+\)$/\t\t/p' | sort -k2) | awk '{print " " }' | while read FILE PREFIX; do echo mv -v "$FILE" "$PREFIX$FILE"; done
mv -v barstring.bar meh_barstring.bar
mv -v dingdongstring.bar w_h.a.t_e_v_e.r_dingdongstring.bar
mv -v foostring.bar aha_foostring.bar
mv -v fuustring.bar lol_fuustring.bar
如果它会显示预期的命令,则在 mv
和 运行 之前删除 echo
以进行更改。
另请注意,我使用 ls -1 .
命令显示当前目录的文件,可能您需要更改目录或在包含文件的目录中使用 运行 命令。
小说明:
该代码背后的想法是为 .bar 和 .abc 文件创建文件名公共部分对:
$ ls -1 . | sed -n '/\.bar/s/^\(.*\)\(\.[^.]\+\)$/\t/p' | sort -k2
barstring.bar barstring
dingdongstring.bar dingdongstring
foostring.bar foostring
fuustring.bar fuustring
$ ls -1 . | sed -n '/\.abc/s/^\(.\+_\)\?\([a-zA-Z0-9]\+\)\(\.[^.]\+\)$/\t\t/p' | sort -k2
meh_barstring.abc barstring meh_
w_h.a.t_e_v_e.r_dingdongstring.abc dingdongstring w_h.a.t_e_v_e.r_
aha_foostring.abc foostring aha_
lol_fuustring.abc fuustring lol_
如您所见,第二个字段是公共部分。之后我们通过公共部分将这些列表连接在一起,只留下 .abc 文件名和前缀:
$ join -j 2 <(ls -1 . | sed -n '/\.bar/s/^\(.*\)\(\.[^.]\+\)$/\t/p' | sort -k2) <(ls -1 . | sed -n '/\.abc/s/^\(.\+_\)\?\([a-zA-Z0-9]\+\)\(\.[^.]\+\)$/\t\t/p' | sort -k2) | awk '{print " " }'
barstring.bar嗯_
dingdongstring.bar w_h.a.t_e_v_e.r_
foostring.bar啊哈_
fuustring.bar哈哈_
最后一步是通过添加适当的前缀来重命名文件。
我有很多文件名中有匹配的字符串。
foostring.bar
barstring.bar
fuustring.bar
aha_foostring.abc
meh_barstring.abc
lol_fuustring.abc
...
我需要找到具有匹配字符串的 bar 和 abc 文件,并将 *.bar-files basename 重命名为 *.abc-files 的样子。也就是说,加一个字符串前缀。
我正在寻找的结果应该是这样的:
aha_foostring.bar
meh_barstring.bar
lol_fuustring.bar
aha_foostring.abc
meh_barstring.abc
lol_fuustring.abc
...
澄清编辑:*.abc 文件中的字符串始终位于最后一个下划线 _
之后和点 .
之前 字符串只包含字母和数字。前缀可以包含任意数量的字符和任意类型的字符,包括 _
和 .
这意味着我还需要考虑以下示例。
dindongstring.bar
w_h.a.t_e_v_e.r_dingdongstring.abc
我一直在试验查找、前缀和基本名称,但我需要这里的帮助和建议。
谢谢
我会选择这样的东西: (我相信有更优雅的方法来做到这一点(awk/sed))
#!/bin/bash
for filename in *.abc
do
prefix=${filename%_*}
searchstring=${filename%.abc}
searchstring=${searchstring#*_}
if [[ -f "$searchstring.bar" ]]
then
mv "${searchstring}.bar" "${prefix}_${searchstring}.bar"
fi
done
# show the result
ls -al
很抱歉在您的答案中添加了这个,但是因为我已经删除了我的答案并且您的答案最接近 OP 的需要。 (我不介意...我关心解决方案=)
编辑: 可能这就是 OP 想要的:
for f in *.abc; do
prefix=${f%_*}
bar=${f%.abc}
bar="${bar##*_}.bar"
[[ -f "$bar" ]] && mv "$bar" "${prefix}_${bar}"
done
我建议尝试以下 "magick":
$ join -j 2 <(ls -1 . | sed -n '/\.bar/s/^\(.*\)\(\.[^.]\+\)$/\t/p' | sort -k2) <(ls -1 . | sed -n '/\.abc/s/^\(.\+_\)\?\([a-zA-Z0-9]\+\)\(\.[^.]\+\)$/\t\t/p' | sort -k2) | awk '{print " " }' | while read FILE PREFIX; do echo mv -v "$FILE" "$PREFIX$FILE"; done
mv -v barstring.bar meh_barstring.bar
mv -v dingdongstring.bar w_h.a.t_e_v_e.r_dingdongstring.bar
mv -v foostring.bar aha_foostring.bar
mv -v fuustring.bar lol_fuustring.bar
如果它会显示预期的命令,则在 mv
和 运行 之前删除 echo
以进行更改。
另请注意,我使用 ls -1 .
命令显示当前目录的文件,可能您需要更改目录或在包含文件的目录中使用 运行 命令。
小说明:
该代码背后的想法是为 .bar 和 .abc 文件创建文件名公共部分对:
$ ls -1 . | sed -n '/\.bar/s/^\(.*\)\(\.[^.]\+\)$/\t/p' | sort -k2
barstring.bar barstring
dingdongstring.bar dingdongstring
foostring.bar foostring
fuustring.bar fuustring
$ ls -1 . | sed -n '/\.abc/s/^\(.\+_\)\?\([a-zA-Z0-9]\+\)\(\.[^.]\+\)$/\t\t/p' | sort -k2
meh_barstring.abc barstring meh_
w_h.a.t_e_v_e.r_dingdongstring.abc dingdongstring w_h.a.t_e_v_e.r_
aha_foostring.abc foostring aha_
lol_fuustring.abc fuustring lol_
如您所见,第二个字段是公共部分。之后我们通过公共部分将这些列表连接在一起,只留下 .abc 文件名和前缀:
$ join -j 2 <(ls -1 . | sed -n '/\.bar/s/^\(.*\)\(\.[^.]\+\)$/\t/p' | sort -k2) <(ls -1 . | sed -n '/\.abc/s/^\(.\+_\)\?\([a-zA-Z0-9]\+\)\(\.[^.]\+\)$/\t\t/p' | sort -k2) | awk '{print " " }'
barstring.bar嗯_ dingdongstring.bar w_h.a.t_e_v_e.r_ foostring.bar啊哈_ fuustring.bar哈哈_
最后一步是通过添加适当的前缀来重命名文件。