使用awk替换特定值(从另一个文件)

时间:2015-06-02 20:06:23

标签: shell awk

我有一个以下文件。

File1中

a b 1
c d 2
e f 3

文件2

x l
y m
z n

我希望一次1替换x并保存在file3中。下次1y并保存在file4

然后文件看起来像

文件3

a b x
c d 2
e f 3

FILE4

a b y
c d 2
e f 3

我完成了xyz,然后2 lmn

我从这开始,但它插入但不替换。

awk -v r=1 -v c=3 -v val=x -F, '
    BEGIN{OFS=" "}; NR != r; NR == r {$c = val; print}
' file1 >file3

1 个答案:

答案 0 :(得分:0)

这是一个gnu awk脚本(因为它使用了多维数组,数组排序),可以做你想做的事情:

#!/usr/bin/awk -f

BEGIN { fcnt=3 }

FNR==NR { for(i=1;i<=NF;i++) f2[i][NR]=$i; next }

{
    fout[FNR][1] = $0
    ff = $NF
    if(ff in f2) {
        for( r in f2[ff]) {
            $NF = f2[ff][r]
            fout[FNR][fcnt++] = $0
        }
    }
}

END {
    for(f=fcnt-1;f>=3;f--) {
        for( row in fout ) {
            if( fout[row][f] != "" ) out = fout[row][f]
            else out = fout[row][1]
            print out > "file" f
        }
    }
}

我对输入数据做了至少一个主要假设:

  • file2中的字段编号与file1中需要替换的值完全对应。例如,xfile2中的字段1,1是输出文件中需要替换的内容。

以下是细分:

  • fcnt=3区块中设置BEGIN
  • FNR==NR - 将File2数组中f2的内容存储为(字段编号,行号)。
  • 将原始f1行存储在fout中(行号,1) - 其中1是一个特殊的可用数组位置(因为fcnt从3开始)
  • $NF保存为ff,因为它将被重置
  • 每当fff2数组的第一个下标中的字段编号时,请将$NF重置为file2的值,然后将结果分配给{{ 1}} at(行号,文件号)为fout(重新计算)。
  • $0中,以相反的顺序遍历END,并将fcnt设置为替换的行值或out顺序的原始行值,将row打印到所需的文件名。

它可以像out一样运行(注意文件顺序)。我得到以下输出:

gawk -f script.awk file2 file1

只需在$ cat file[3-8] a b x c d 2 e f 3 a b y c d 2 e f 3 a b z c d 2 e f 3 a b 1 c d l e f 3 a b 1 c d m e f 3 a b 1 c d n e f 3 块中执行查找,就可以提高内存的效率,但我希望利用END重新计算,而不是需要调用$0 split