如果脚本逐行处理,如何返回处理上一行?

时间:2013-05-03 09:56:01

标签: shell unix sed awk

以下是我的样本清单:

AAA BBB CCC1
DDD EEE FFF1
GGG HHH III1           <----- I want to remove this
GGG HHH III3 >>updated <----- I want to keep this
JJJ KKK LLL7

当我使用For循环浏览列表时,我想记下其中包含“&gt;&gt;更新”的每一行并返回一行并删除旧行(未更新)和然后在“&gt;&gt; updated”行之后前进到下一行。所以基本上我的最终输出是:

AAA BBB CCC1
DDD EEE FFF1
GGG HHH III3
JJJ KKK LLL7

我使用awk来解析shell脚本中其他字段的值,但我不太确定如何向前和向后执行此操作。任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:5)

awk '{a=$0;getline; if ($0~/>>updated/)print $1,$2,$3; else print a,"\n"$0}' file
AAA BBB CCC1
DDD EEE FFF1
GGG HHH III3
JJJ KKK LLL7

答案 1 :(得分:4)

这可能适合你(GNU sed):

sed -r '$!N;s/.*\n(.*)\s+>>updated\s*$/\1/;P;D' file

在模式空间中保留两行,并在最后一行符合您要求时删除第一行。

awk解决方案可能是:

awk 'sub(/ *>>updated.*/,""){l=$0;next};NR>1{print l};{l=$0};END{print l}' file

答案 2 :(得分:3)

tac很好但不是所有发行版的默认值。如果你没有它,这里有一个awk单流程单行:

awk -F' >>' 'p{if($2~/updated/){p=$1;next}print p}{p=$0}END{print p}' file

答案 3 :(得分:1)

perl -lne 'if(/\>\>updated/){pop @a;s/\>\>updated//g;push @a,$_}else{push @a,$_}END{print join "\n",@a}' your_file

测试:

> cat temp
AAA BBB CCC1
DDD EEE FFF1
GGG HHH III1
GGG HHH III3 >>updated
JJJ KKK LLL7
> perl -lne 'if(/\>\>updated/){pop @a;s/\>\>updated//g;push @a,$_}else{push @a,$_}END{print join "\n",@a}' temp
AAA BBB CCC1
DDD EEE FFF1
GGG HHH III3 
JJJ KKK LLL7
>

答案 4 :(得分:1)

最简单的方法是在输入文件中建立一个行数组,但只有在没有更新&gt;&gt;更新时才增加数组索引,以便包含&gt;&gt;更新的行覆盖上一个条目数组,然后在到达文件末尾时打印数组的内容:

$ cat file
AAA BBB CCC1
DDD EEE FFF1
GGG HHH III1           <----- I want to remove this
GGG HHH III3 >>updated <----- I want to keep this
JJJ KKK LLL7

$ awk '!/>>updated/{++numLines} {line[numLines]=$0} END {for (nr=1;nr<=numLines;nr++) print line[nr]}' file
AAA BBB CCC1
DDD EEE FFF1
GGG HHH III3 >>updated <----- I want to keep this
JJJ KKK LLL7

如果您想要删除该行上的&gt;&gt;更新和后续文本,您可以将测试存在更改为测试以尝试删除它:

$ awk '!sub(/ *>>updated.*/,""){++numLines} {line[numLines]=$0} END{for (nr=1;nr<=numLines;nr++) print line[nr]}' file
AAA BBB CCC1
DDD EEE FFF1
GGG HHH III3
JJJ KKK LLL7

如果&gt;&gt;已更新,那么sub()将删除它并返回成功,因此您知道&gt;&gt;已更新,否则sub()将不执行任何操作,但返回失败,因此您知道&gt ;&gt;更新缺席。