我需要替换来自不同文件的文件中的模式作为输入。
假设 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
“文件本地”BEGIN
和END
块。
在这里,我们将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
这有点低效,但它的作用是,对于第二个文件中的每一行,它设置OFS
和FS
并;
重新分割输入。
一个稍微更有效(但仍然丑陋)的变体是仅设置OFS
第二FS
个文件中的第一行:
awk 'FNR == NR { pat[$2] = $1; next } FS != ";" { OFS = FS = ";"; $0=$0 } ($6 in pat) { $6 = pat[$6] } { print }' file1 file2