替换列中的模式

替换列中的模式

我需要替换来自不同文件的文件中的模式作为输入。

假设 file1 内容:

ab 10
bc 20
cd 30
de 40

文件2:

server1;10 feb 2020;disk5;123455678;comment;10;1;desc;abcde3;987654
server1;10 feb 2020;disk6;123455678;comment;10;7;desc;abcde3;987654
server1;10 feb 2020;disk10;123455678;comment;20;4;desc;abcde3;987654
server1;10 feb 2020;disk1;123455678;comment;30;5;desc;abcde3;987654
server1;10 feb 2020;disk9;123455678;comment;20;4;desc;abcde3;987654
server1;10 feb 2020;disk2;123455678;comment;40;6;desc;abcde3;987654
server1;10 feb 2020;disk5;123455678;comment;30;8;desc;abcde3;987654

在这里,作为;file2 中的分隔符,我想用 file1 中的匹配值替换第 6 列。

IE

server1;10 feb 2020;disk5;123455678;comment;**ab**;1;desc;abcde3;987654

我知道它可以通过awk/ sed。你能帮忙吗?注意:我们不使用 GNU 版本的awk/sed作为其AIX.

答案1

假设所有 $6 值都包含在 file1 中,请尝试

awk 'FNR == NR {T[$2] = $1; next} {$6 = T[$6]} 1' file1 FS=";" OFS=";" file2

答案2

本练习的难点在于如何在同一个awk程序中处理不同的字段分隔符。

使用 GNU awk

$ gawk 'FNR == NR { pat[$2] = $1; next } ($6 in pat) { $6 = pat[$6] } { print } ENDFILE { OFS = FS = ";" }' file1 file2
server1;10 feb 2020;disk5;123455678;comment;ab;1;desc;abcde3;987654
server1;10 feb 2020;disk6;123455678;comment;ab;7;desc;abcde3;987654
server1;10 feb 2020;disk10;123455678;comment;bc;4;desc;abcde3;987654
server1;10 feb 2020;disk1;123455678;comment;cd;5;desc;abcde3;987654
server1;10 feb 2020;disk9;123455678;comment;bc;4;desc;abcde3;987654
server1;10 feb 2020;disk2;123455678;comment;de;6;desc;abcde3;987654
server1;10 feb 2020;disk5;123455678;comment;cd;8;desc;abcde3;987654

在这里,我们开始读取第一个文件,用pat我们稍后想要在第 6 列中替换的内容填充关联数组。键是我们替换的东西,值是我们替换它们的东西。

当 GNUawk完成读取文件时,它会执行该ENDFILE块(如果存在)(还有一个BEGINFILE块在某些情况下可能有用)。 ENDFILE类似于BEGINFILE“文件本地”BEGINEND块。

在这里,我们将ENDFILE输入和输出字段分隔符更改为分号。

读取第二个文件时,我们只需测试第 6 个字段中的数据是否可用作键pat,如果是,我们将其值替换为该键的值。无论是否修改,都会打印第二个文件中的所有行。

对于非 GNU awk,可以这样做:

$ awk 'FNR == NR { pat[$2] = $1; next } { OFS = FS = ";"; $0=$0 } ($6 in pat) { $6 = pat[$6] } { print }' file1 file2
server1;10 feb 2020;disk5;123455678;comment;ab;1;desc;abcde3;987654
server1;10 feb 2020;disk6;123455678;comment;ab;7;desc;abcde3;987654
server1;10 feb 2020;disk10;123455678;comment;bc;4;desc;abcde3;987654
server1;10 feb 2020;disk1;123455678;comment;cd;5;desc;abcde3;987654
server1;10 feb 2020;disk9;123455678;comment;bc;4;desc;abcde3;987654
server1;10 feb 2020;disk2;123455678;comment;de;6;desc;abcde3;987654
server1;10 feb 2020;disk5;123455678;comment;cd;8;desc;abcde3;987654

这有点低效,但它的作用是,对于第二个文件中的每一行,它设置OFSFS;重新分割输入。

一个稍微更有效(但仍然丑陋)的变体是仅设置OFS第二FS个文件中的第一行:

awk 'FNR == NR { pat[$2] = $1; next } FS != ";" { OFS = FS = ";"; $0=$0 } ($6 in pat) { $6 = pat[$6] } { print }' file1 file2

相关内容