如何使用sed打印文件中的第6行,但前提是文件中的任何其他行与模式匹配



并且,以一种更通用的方式,是否可以使用sed程序打印任何与模式1匹配的行,但前提是文件中的任何其他行与模式2匹配?它可以用grep命令的组合来完成,但我正试图用一个sed命令来完成。

这不是sed的作业:

awk 'NR==FNR{if (/PATTERN2/) f=1; next} f && (FNR==6)' file file
awk 'NR==FNR{if (/PATTERN2/) f=1; next} f && /PATTERN1/' file file

或者如果您不想指定两次文件名:

awk 'BEGIN{ARGV[ARGC]=ARGV[ARGC-1]; ARGC++} NR==FNR{if (/PATTERN2/) f=1; next} f && /PATTERN1/' file

我相信这是可能的:

:l1 {
    /foo/ { H }
    /bar/ { x ; s/^n//; p ; s/.*//; h ; b l2}
    n
    b l1
}
:l2 {
    /foo/ { p }
    n
    b l2
}

快速概览:

l1是我们的初始循环。它将检查/foo/(为模式1(。如果它是在一条线上找到的,那么这条线就会被吸引到容纳空间。下一行将检查/bar/,当找到时,它将交换保持空间和模式空间(x(,从数据中删除一个初始换行符(这是因为我们在第一行中使用H,我们p打印数据,我们清空此数据并将其存储回保持模式中(因此它将为空(。然后,我们b分支到l2,实际上,离开了循环l2

如果该行与模式1 foo或模式2 bar不匹配,它将转到下一行,并再次跳回到起始l1

一旦我们进入l2,我们就检查模式1 /foo/。既然我们知道我们早些时候发现了模式2(否则我们就不会在这里了(,我们就可以安全地打印这些数据。如果不是foo,我们就跳过这一行,循环回到l2的开头。

用以下数据进行了大量测试:

a
b
c foo
d
e foo
f bar
g foo
h
i foo
j
k

根据存在的"条",它要么用foo打印所有行,要么什么都不打印。

诚然,它不会赢得任何选美比赛,但它只是用sed写的。

这里有一个sed脚本,它打印匹配pattern1的行,如果存在匹配pattern2的行,则不管pattern1、pattern2:的顺序如何

#n
:loop 
    /foo/H
    /bar/{      
        g
        s/n//
        /foo/p          
        :loop2 
            n
            /foo/p              
            b loop2         
    }
    n
    b loop

如果你把它保存到像s.sed这样的文件中,你就可以进行

sed -f s.sed file

#n的工作方式与-n相同,表示抑制标准输出。loop将匹配foo(pattern1(的任何行附加到保持空间。当它遇到条(pattern2(时,它会用g命令获取保持空间的内容(擦除当前的模式空间(。它删除第一个新行(因为即使保持空间为空,H命令也会添加新行(。如果它包含foo(意味着它不是空的(,它就会打印出模式空间。然后n转到下一行。现在我们已经匹配了pattern2,我们可以通过启动loop2

来安全地打印foo的所有匹配

这可能对你有用(GNU sed(:

sed -n ':a;6H;/pattern/{z;H};n;$!ba;x;s/n//;s///p' file

使用选项-n关闭图案空间的自动打印。设置一个循环,读取文件的每一行,并在保持空间中附加一行(针对第6行(和/或空行(表示已在pattern上发生匹配(。在文件交换到保留空间结束时,删除一直存在的第一个换行符(如果附加了一行或空行(,并删除第二个换行符,如果成功,则打印结果。

N。B.如果文件中存在pattern,则保留空间将包含两个换行符——前两个字符或第一个和最后一个字符。

在一般情况下,如果不解析两次文件,就无法做到这一点。这意味着调用sed两次。

如果匹配"触发模式"的行总是在匹配"匹配模式"的所有行出现之后出现,那么这可能会为您做到:

$ cat testdata
1 aaa
2 match
3 match
4 ddd
5 trigger (only print line 2 and 3 if this line is present)
$ sed -n -e '/match/H' -e '/trigger/{x;^Mp;^M;q^M}' testdata
2 match
3 match

(^M中有逐字换行(

我不知道如何删除输出中最初的空行。欢迎对此提出意见。

更新:我在"触发器模式"的命令序列的末尾放了一个最终的q(退出(,只是为了确保文件后面的其他触发器模式不会破坏输出。

相关内容

最新更新