使用文本文件中的前缀重命名文件

时间:2016-11-02 21:22:50

标签: regex awk sed

我有一组名为

的文件
sample_exp_A1_A01
sample_exp_A2_A02
sample_exp_A3_A03
sample_exp_A4_A04
sample_exp_A5_A05

我有一个包含以下值的文本文件

A01 170
A02 186
A03 165
A04 130
A05 120

我想根据文本文件值重命名文件,如

FS_170_sample_exp_A1_A01
FS_186_sample_exp_A2_A02
FS_165_sample_exp_A3_A03
FS_130_sample_exp_A4_A04
FS_120_sample_exp_A5_A05

因此,请根据A01A02A03A04匹配文本文件中的ID,然后将相应的数字作为前缀添加到文件名中。此外,还为所有文件名添加前缀FS,如上所示。

我手动尝试这样做,但一次只能用于一个文件

rename 's/^/FS_170_/' *A01 

获取

FS_170_sample_exp_A1_A01

1 个答案:

答案 0 :(得分:6)

假设您的后缀位于名为suffix的文件中,您可以这样做:

for fname in sample*; do
    echo mv "$fname" FS_"$(awk -v pf="${fname##*_}" \
        '$1 == pf {print $2}' suffix)"_"$fname"
done

它遍历所有文件;在循环中,它通过预先加FS_

的输出将新文件名放在一起
awk -v pf="${fname##*_}" '$1 == pf {print $2}' suffix

这会将输入文件名的最后一部分分配给awk变量pf,然后,对于suffix中第一个字段与该变量匹配的行,打印第二个字段。

或者,如果你有一个支持Perl兼容正则表达式的grep,你可以使用grep -Po "${fname##*_} \K.*" suffix代替(使用可变大小的look-behind,\K):

for fname in sample*; do
    echo mv "$fname" FS_"$(grep -Po "${fname##*_} \K.*" suffix)"_"$fname"
done

这将添加到新文件名中,新名称的其余部分是完整的旧名称。

对于您的输入文件,这会产生

mv sample_exp_A1_A01 FS_170_sample_exp_A1_A01
mv sample_exp_A2_A02 FS_186_sample_exp_A2_A02
mv sample_exp_A3_A03 FS_165_sample_exp_A3_A03
mv sample_exp_A4_A04 FS_130_sample_exp_A4_A04
mv sample_exp_A5_A05 FS_120_sample_exp_A5_A05

要实际重命名文件,必须删除echo

如果suffix是巨大的,你可以通过在第一场比赛后退出来加速这一点:

awk -v pf="${fname##*_}" '$1 == pf {print $2; exit}' suffix

或grep在第一场比赛后停止:

grep -m 1 -Po "${fname##*_} \K.*" suffix