Sol*_*osa 3 awk text-processing
我有 2 列文件,如:
$ cat data
a4 b1
a4 c2
a4 b4
z4 c2
Run Code Online (Sandbox Code Playgroud)
我想匹配两列,例如如果(column1 = a4 and column2 = b1)
OR(column1 = a4 and column2 = c2)
那么 column3 中的输出应该是
(期望的输出):
a4 b1 matched
a4 c2 matched
a4 b4 -
z4 c2 -
Run Code Online (Sandbox Code Playgroud)
所以我尝试将我的逻辑合并到 1 个 liner awk 中:
$ awk '{print $1, $2, (($1 = a4 && $2 = b1) || ($1 = a4 && $2 = c2) ? "a4-matched" : "-")}' data
Run Code Online (Sandbox Code Playgroud)
我得到了 - 对于整个 column3,我想我的 awk 语法错误,或者缺少其他东西 - 以下是结果:
a4 b1 -
a4 c2 -
a4 b4 -
z4 c2 -
Run Code Online (Sandbox Code Playgroud)
你快到了,但你似乎引入了一个语法错误:$1=a4
不会检查第一列是否等于a4
,而是将awk
变量的内容a4
(未定义,因此为空)分配给第一列,从而覆盖其内容(您已经打印了,所以您没有注意到)并且还评估为“false”,因为未初始化的变量评估为“false”。您的其他比较也是如此。这就是为什么您永远不会将“匹配”条件设为“真”的原因。
通过(小)所需的更正,程序将如下所示:
awk '{if (($1=="a4" && $2=="b1") || ($1=="a4" && $2=="c2")) $3="matched"; else $3="-"} 1' data.txt
Run Code Online (Sandbox Code Playgroud)
它的工作原理如下:
$3
-
matched
1
在规则块之外流浪的含义-awk
如果遇到在规则之外评估为“真”的条件,将打印当前行,包括任何先前的修改。请注意,上面的程序是为了便于理解和演示这一点而明确编写的。在您的情况下可以缩短它,因为条件对于$1
以下两种“允许”情况是相同的$2
:
awk '{if ($1=="a4" && ($2=="b1" || $2=="c2")) $3="matched"; else $3="-"} 1' data.txt
Run Code Online (Sandbox Code Playgroud)
另请注意,修改任何字段将导致awk
使用输出字段分隔符(默认为一个空格)从其各个字段重建行,因此如果输入字段被多个空格分隔,则原始格式将被破坏。如果这是一个问题,您应该使用您在尝试中已经选择的“附加”策略,尽管您应该打印而不是.$0, ( your conditional string )
$1, $2, ( your conditional string )
您不需要检查$1
两次,检查一次,因为在这两种情况下它的条件相同,并且$2
对不同的选项进行多次检查。请注意,分配新字段将导致使用默认值(单个空格字符)awk
重建字段,如果您的输入中有任何空格,这将导致将连续的空格压缩为一个。$0
OFS
awk '{ print $0, ($1=="a4" && ($2=="b1" || $2=="c2")?"matched":"-") }' infile
Run Code Online (Sandbox Code Playgroud)
$ awk '{print $0, ($1=="a4" && ($2 ~ /^(b1|c2)$/) ? "matched" : "-")}' file
a4 b1 matched
a4 c2 matched
a4 b4 -
z4 c2 -
Run Code Online (Sandbox Code Playgroud)