将多个字符串替换 awk 命令合并为一个

combine multiple string replacement awk commands into one

我有两个单独的 awk 命令,它们将 destination_file 的第三列特定行替换为源文件的第三列特定行。这些命令有效,但对于大量 IO 操作来说很麻烦。有没有办法将 awk 命令合二为一?

我现在的命令是:

z2=$(awk 'NR==12 { print }' ../source_folder/source_file)
z3=$(awk 'NR==14 { print }' ../source_folder/source_file)


awk -v z2=$z2 'NR==10{=z2} 1' destination_file > temp && mv temp destination_file
awk -v z3=$z3 'NR==11{=z3} 1' destination_file > temp && mv temp destination_file

作为此问题的扩展,我获得的 z2、z3、z4 值的行来自 NR==12、14、16 ... 以及 destination_file 中的行我要替换的是 NR==10, 11, 12 ...;有没有一种方法可以编写一个序列来执行此字符串替换操作,而不是列出所有 z1、z2、z3 ...?

您可以将两个程序合二为一。只有 1 个 awk 程序来检查条件 NR==10NR==11,并根据条件为各个字段分别赋值。这会将输出保存到输出文件中。

z2=$(awk 'NR==12 { print }' ../source_folder/source_file)
z3=$(awk 'NR==14 { print }' ../source_folder/source_file)

awk -v z2="$z2"  -v z3="$z3" 'NR==10{=z2} NR==11{=z3} 1' destination_file > temp && mv temp destination_file

为此您不需要多次调用 awk 和 shell 变量:

awk '
    NR==FNR {
        if      ( FNR==12 ) { map[10] =  }
        else if ( FNR==14 ) { map[11] = ; nextfile }
        next
    }
    FNR in map {
         = map[FNR]
    }
    { print }
' ../source_folder/source_file destination_file

或者如果您的行号在源文件中总是增加 2,而在目标文件中总是增加 1:

awk '
    NR==FNR {
        if ( (12 <= FNR) && !(FNR%2) ) {
            map[10 + (c++)] = 
        }
        next
    }
    FNR in map {
         = map[FNR]
    }
    { print }
' ../source_folder/source_file destination_file