我有很多文件名中包含匹配字符串的文件。
foostring.bar
barstring.bar
fuustring.bar
aha_foostring.abc
meh_barstring.abc
lol_fuustring.abc
...
我需要找到带有匹配字符串的bar和abc文件,并将* .bar-files基本名称重命名为* .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
我一直在尝试使用find,prefix和basename,但我需要帮助和建议。
由于
答案 0 :(得分:2)
我会这样做: (我相信有更优雅的方法(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
答案 1 :(得分:1)
我建议尝试下面的“魔法”:
$ join -j 2 <(ls -1 . | sed -n '/\.bar/s/^\(.*\)\(\.[^.]\+\)$/\1\2\t\1/p' | sort -k2) <(ls -1 . | sed -n '/\.abc/s/^\(.\+_\)\?\([a-zA-Z0-9]\+\)\(\.[^.]\+\)$/\1\2\3\t\2\t\1/p' | sort -k2) | awk '{print $2 " " $4}' | 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
如果它会显示预期的命令,请在echo
之前移除mv
,然后再次运行以进行更改。
另请注意,我使用ls -1 .
命令显示当前目录的文件,可能需要在目录中更改目录或运行命令。
小解释:
该代码背后的想法是为.bar和.abc文件创建成对的文件名 - 公共部分:
$ ls -1 . | sed -n '/\.bar/s/^\(.*\)\(\.[^.]\+\)$/\1\2\t\1/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]\+\)\(\.[^.]\+\)$/\1\2\3\t\2\t\1/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/^\(.*\)\(\.[^.]\+\)$/\1\2\t\1/p' | sort -k2) <(ls -1 . | sed -n '/\.abc/s/^\(.\+_\)\?\([a-zA-Z0-9]\+\)\(\.[^.]\+\)$/\1\2\3\t\2\t\1/p' | sort -k2) | awk '{print $2 " " $4}'
barstring.bar meh_ dingdongstring.bar w_h.a.t_e_v_e.r_ foostring.bar aha_ fuustring.bar lol _
最后一步是通过向它们添加适当的前缀来重命名文件。