我的文本文件看起来像这样:
bla : 1 - etc
blb : a - etc
blc : 2 - etc
bld : 3 - etc
ble : 1 - etc
blf : 1 - etc
blg : a - etc
blh : 1 - etc
bli : a - etc
我正在文件中搜索模式
": 1 -"
。一些连续的行具有相同的模式,我需要这两行加上下一行。
ble : 1 - etc
blf : 1 - etc
blg : a - etc
是否可以使用
grep
、sed
或任何其他工具提取此行?
使用 awk 这是一个相当简单的任务:
awk -F ' [:-] ' '
$2 == prev2 { # if the 2nd field matches the previous 2nd field,
print prevline # print the previous line
print # print the current line
getline; print # get the next line and print it
}
{prev2 = $2; prevline = $0} # remember these values for the next iteration
' file
我会使用
awk
而不是 sed
:
awk -F: 'm~$2{print m;print;getline;print}{m=$0}' input.txt
m
是保存最后一行的变量。如果它与 :
后面的部分匹配,我们将打印 m
和当前行,然后获取下一行并打印它。最后 m=$0
将当前行存储在 m
中。
awk 比 sed 更适合像“if”这样的逻辑结构。
$ awk 'substr($0,4,5)==last{print lastline;print;getline;print;} {last=substr($0,4,5);lastline=$0;}' input.txt
ble : 1 - etc
blf : 1 - etc
blg : a - etc
我假设您知道自己需要什么,而不是用空格分隔的字段来分割行,并且
: 1 -
确实是您正在寻找的东西。如果您的输入数据与您的示例不匹配,请随时更正。
您可以使用egrep:
egrep -A2 ": 1 -" filename
其中 A2 显示找到模式后接下来的两行。
输出:
bla : 1 - etc
blb : a - etc
blc : 2 - etc
--
ble : 1 - etc
blf : 1 - etc
blg : a - etc
blh : 1 - etc
bli : a - etc
是的,awk:
awk '/: 1 -/ {++i}
i>1 {print p}
!/: 1 -/ {if(i>1)print;i=0}
{p=$0}
END {if(i>1)print p}'
awk '$1 ~/^bl$|e|f|g/' file
ble : 1 - etc
blf : 1 - etc
blg : a - etc
如果第一列以 bl 开头并以 e、f 或 g 结尾,则打印这些行。
awk '/: 1 -/ {CNT++; x[CNT]=$0; next} CNT==2 {print x[1]; print x[2]; print $0} {CNT=0}' *.*