假设我有如下文本文件:
R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
我想用awk
不同的方式处理这些行,比如
awk '/R1/ { print "=>" $0} /R2/ { print "*" $0} '
我还想按原样打印所有其余的行(不重复我已经处理过的行),基本上我需要 /ELSE/ { print $0}
在行的末尾添加一个awk
。
有这样的事吗?
答案1
简化方法awk
awk '/R1/ {print "=>" $0;next} /R2/{print "*" $0;next} 1' text.file
[jaypal:~/Temp] cat text.file
R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
[jaypal:~/Temp] awk '/R1/ { print "=>" $0;next} /R2/{print "*" $0;next}1' text.file
=>R1 12 324 3453 36 457 4 7 8
*R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
[jaypal:~/Temp]
模式 {Action} 语句的突破:
/R1/ { print "=>" $0;next}
:表示将执行有/R1/
打印动作的行。意味着 awk 语句的其余部分将被忽略,并且将查看下一行。=>
next
/R2/{print "*" $0;next}
:这意味着将执行与pattern /R2/
打印操作相匹配的行。*
当awk
处理开始时,第一个pattern {action}
语句将被忽略,因为pattern /R1/
对于具有/R2/
.这样第二条pattern {action}
语句就完成了就行了。next
再次意味着我们不想再进行任何处理,awk
并将适当地转到下一行。1
打印所有行。当只提供 no 条件时{action}
,awk 默认使用 using{print}
。这里的条件 is1
被解释为 true,所以它总是成功。如果我们到达这一点,这是因为第一条和第二条pattern {action}
语句被忽略或绕过(对于不包含/R1/
and 的行/R2/
),因此将对其余行执行默认打印操作。
答案2
awk
实现了条件语句中常见的嫌疑。最好使用它printf
来代替print
您想要在比赛中完成的工作。
awk '{ if (/^R1/) { printf("=> %s\n", $0) } else if (/^R2/) { printf("* %s\n", $0) } else { print $0 } }'
答案3
Chris Down 已经展示了如何通过在块中使用显式“if”语句来获得正则表达式的 else。您还可以通过其他一些方式获得相同的效果,尽管他的解决方案可能更好。
一种是编写第三个正则表达式,它仅匹配其他不匹配的文本,在您的情况下,这看起来像这样:
awk '/^R1/ { print "=>" $0}
/^R2/ { print "*" $0}
/^[^R]/ || /^R[^12]/ { print $0 } '
请注意,这使用锚定的正则表达式 - 正则表达式开头的 ^ 仅在行的开头匹配 - 您的原始模式没有这样做,这会稍微减慢匹配速度,因为它将检查一行上的所有字符而不是跳到下一行。第三种(“else”)情况将匹配以非“R”([^R])的某个字符开头的行,或者以“R”开头后跟不是“1”或“”的字符的行。 2'(R[^12])。 ^ 的两种不同含义有点令人困惑,但这个错误是很久以前就犯的,不会很快改变。
要使用互补的正则表达式,它们确实需要锚定,否则 [^R] 将匹配其后面的 1。对于像您这样非常简单的正则表达式,此方法可能很有用,但随着正则表达式变得更加复杂,此方法将变得难以管理。相反,您可以为每行使用状态变量,如下所示:
awk '{ handled = 0 }
/^R1/ { print "=>" $0; handled = 1}
/^R2/ { print "*" $0; handled = 1}
{ if (!handled) print $0 } '
这会将每个新行的处理设置为零,如果它与两个正则表达式中的任何一个匹配,则设置为 1,最后,如果它仍然为零,则执行打印 $0。