让我们说我有一个包含数百万行的文件,组织如下:
@1:N:0:ABC
XYZ
@1:N:0:ABC
ABC
我正在尝试编写一行grep / sed / awk匹配函数,如果在第二行找到第一行的NCCGGAGA
行,则返回两行。
当我尝试使用grep -A1 -P
并使用'(?<=:)[A-Z]{3}'
之类的匹配来管理匹配时,我会陷入困境。我认为我的创造力让我失望了。
答案 0 :(得分:6)
使用awk
$ awk -F: 'NF==1 && $0 ~ s{print p ORS $0} {s=$NF; p=$0}' ip.txt
@1:N:0:ABC
ABC
-F:
使用:
作为分隔符,可以轻松获取最后一栏s=$NF; p=$0
保存上一列值和整行以便稍后打印NF==1
如果行不包含:
$0 ~ s
如果line包含之前保存的最后一列数据
index($0,s)
代替字面搜索:
后跟没有:
的行
使用GNU sed
(也可以与其他版本一起使用,语法可能会有所不同)
$ sed -nE '/:/{N; /.*:(.*)\n.*\1/p}' ip.txt
@1:N:0:ABC
ABC
/:/
,则:
N
在模式空间中添加下一行/.*:(.*)\n.*\1/
在最后:
之后捕获字符串并检查它是否出现在下一行再次,这假设输入如问题所示..这不适用于像
这样的情况@1:N:0:ABC
@1:N:0:XYZ
XYZ
答案 1 :(得分:3)
如果您的实际Input_file与显示的示例相同,那么下面的内容也可以为您提供帮助。
awk -v FS="[: \n]" -v RS="" '$(NF-1)==$NF' Input_file
编辑: 此处根据Sundeep建议添加1个解决方案。
awk -v FS='[:\n]' -v RS= 'index($NF, $(NF-1))' Input_file
答案 2 :(得分:3)
这可能适合你(GNU sed):
sed -n 'N;/.*:\(.*\)\n.*\1/p;D' file
使用 grep-like 选项-n
明确打印行。在模式空间中读取两行,如果符合要求则打印两行。始终删除第一个并重复。