用awk在不同行打印满足条件的行
Print line that meets conditions in different lines with awk
总新手。 awk 可以打印以下内容:
w171930 t1 Y z2545377 <--- print this line
w171930 t2 X z4495648
w171931 t1 Y z2555698 <--- print this line
w171931 t2 X z5505690
w171932 t1 Y z2554345 <--- print this line
w171932 t2 X z5507345
w171933 t1 Y z2214694
w171933 t2 Y z8022710
w171933 t3 Y z2143462
w171933 t4 Y z6217556
w171933 t5 Y z9608343
w171933 t6 Y z9984446
w171933 t7 Y z2985572
w171933 t8 Y z6334512 <--- print this line
w171933 t9 X z6503375
w171943 t1 Y z2441603 <--- NO print this line
w171943 t2 X z4644534
w171943 t3 Y z2164440
w171944 t1 Y z2165532
搜索 $3 == "X" 如果下一行有 $2 == "t1"
则打印上一行
目标
w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512
我只打印了前一行,但我不知道如何执行完整的条件
awk ' == "Y" { Y=[=12=]; next; } { if ( =="X") print Y;}'
表达不正确请见谅
awk '=="t1"{ if(prev2!="" && prev!="") print prev2 }
{ prev=(=="X"?prev2:""); prev2=[=10=] }' input
=="t1"
仅适用于第二个元素 = "t1" 的行。当 prev
和 prev2
有值时,我们应该打印该值。
当第三个元素等于“X”时,prev
将包含 prev2
的值
prev2
将具有需要返回的行的值。
另一个解决方案awk
:
$ awk '=="t1" && third=="X"{print line2}
{line2=line1; line1=[=10=]; third=}' ip.txt
w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512
line1
将有前一行,line2
将有前一行但只有一行
third
保存上一行第3个字段内容
- 当当前行的第二个字段为
t1
时,检查上一行的第三个字段是否为X
,如果是,则打印前一行
关于您的要求:
Search on == "X" and print the previous line if the next line has a == "t1"
就像在生活中一样,在软件中,根据已经发生的事情而不是将要发生的事情来做事要容易得多,所以不要根据下一件事来写需求,而是根据上一件事来写需求事情过去了,你会发现概念化和编写代码来实现它们要容易得多。在这种情况下你的要求应该写成:
If == "t1" in the current line and == "X" in the previous line then print the line before that.
这导致明显的实现:
$ awk '(=="t1") && (p3=="X") {print pp0} {pp0=p0; p0=[=12=]; p3=}' file
w171930 t1 Y z2545377 <--- print this line
w171931 t1 Y z2555698 <--- print this line
w171932 t1 Y z2554345 <--- print this line
w171933 t8 Y z6334512 <--- print this line
如果需要,您可以使用 regex 执行此操作,这可以在 Perl 中完成:
perl -0777 -nE 'while (/^.*\R(?=(?:\S+\s){2}X\s\S+\R\S+\st1)/gm) {print $&}' file
或者,对正则表达式稍作修改,您可以使用 GNU Grep:
grep -ozP '.*\R(?=(?:\S+\s){2}X\s\S+\R\S+\st1)' file | tr -d '[=11=]0'
或ruby
:
ruby -e 'puts $<.read.scan(/(.*\R)(?=(?:\S+\s){2}X\s\S+\R\S+\st1)/)' file
其中任何一个(使用您的示例输入)打印:
w171930 t1 Y z2545377 <--- print this line
w171931 t1 Y z2555698 <--- print this line
w171932 t1 Y z2554345 <--- print this line
w171933 t8 Y z6334512 <--- print this line
有点冗长,但它完成了工作:
<<<"${aa}" mawk '
BEGIN {
_+=++_
} {
do {____=$((__=$_)<"")
} while($(_+getline)=="Y")
if(___<("X"==$++_)) {
printf("%s%.*s",____,\
(___=__!="t1")<_,ORS) }; -—_}'
w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512
总新手。 awk 可以打印以下内容:
w171930 t1 Y z2545377 <--- print this line
w171930 t2 X z4495648
w171931 t1 Y z2555698 <--- print this line
w171931 t2 X z5505690
w171932 t1 Y z2554345 <--- print this line
w171932 t2 X z5507345
w171933 t1 Y z2214694
w171933 t2 Y z8022710
w171933 t3 Y z2143462
w171933 t4 Y z6217556
w171933 t5 Y z9608343
w171933 t6 Y z9984446
w171933 t7 Y z2985572
w171933 t8 Y z6334512 <--- print this line
w171933 t9 X z6503375
w171943 t1 Y z2441603 <--- NO print this line
w171943 t2 X z4644534
w171943 t3 Y z2164440
w171944 t1 Y z2165532
搜索 $3 == "X" 如果下一行有 $2 == "t1"
则打印上一行目标
w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512
我只打印了前一行,但我不知道如何执行完整的条件
awk ' == "Y" { Y=[=12=]; next; } { if ( =="X") print Y;}'
表达不正确请见谅
awk '=="t1"{ if(prev2!="" && prev!="") print prev2 }
{ prev=(=="X"?prev2:""); prev2=[=10=] }' input
=="t1"
仅适用于第二个元素 = "t1" 的行。当prev
和prev2
有值时,我们应该打印该值。
当第三个元素等于“X”时,prev
将包含prev2
的值prev2
将具有需要返回的行的值。
另一个解决方案awk
:
$ awk '=="t1" && third=="X"{print line2}
{line2=line1; line1=[=10=]; third=}' ip.txt
w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512
line1
将有前一行,line2
将有前一行但只有一行third
保存上一行第3个字段内容- 当当前行的第二个字段为
t1
时,检查上一行的第三个字段是否为X
,如果是,则打印前一行
关于您的要求:
Search on == "X" and print the previous line if the next line has a == "t1"
就像在生活中一样,在软件中,根据已经发生的事情而不是将要发生的事情来做事要容易得多,所以不要根据下一件事来写需求,而是根据上一件事来写需求事情过去了,你会发现概念化和编写代码来实现它们要容易得多。在这种情况下你的要求应该写成:
If == "t1" in the current line and == "X" in the previous line then print the line before that.
这导致明显的实现:
$ awk '(=="t1") && (p3=="X") {print pp0} {pp0=p0; p0=[=12=]; p3=}' file
w171930 t1 Y z2545377 <--- print this line
w171931 t1 Y z2555698 <--- print this line
w171932 t1 Y z2554345 <--- print this line
w171933 t8 Y z6334512 <--- print this line
如果需要,您可以使用 regex 执行此操作,这可以在 Perl 中完成:
perl -0777 -nE 'while (/^.*\R(?=(?:\S+\s){2}X\s\S+\R\S+\st1)/gm) {print $&}' file
或者,对正则表达式稍作修改,您可以使用 GNU Grep:
grep -ozP '.*\R(?=(?:\S+\s){2}X\s\S+\R\S+\st1)' file | tr -d '[=11=]0'
或ruby
:
ruby -e 'puts $<.read.scan(/(.*\R)(?=(?:\S+\s){2}X\s\S+\R\S+\st1)/)' file
其中任何一个(使用您的示例输入)打印:
w171930 t1 Y z2545377 <--- print this line
w171931 t1 Y z2555698 <--- print this line
w171932 t1 Y z2554345 <--- print this line
w171933 t8 Y z6334512 <--- print this line
有点冗长,但它完成了工作:
<<<"${aa}" mawk '
BEGIN {
_+=++_
} {
do {____=$((__=$_)<"")
} while($(_+getline)=="Y")
if(___<("X"==$++_)) {
printf("%s%.*s",____,\
(___=__!="t1")<_,ORS) }; -—_}'
w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512