使用awk
或sed
如何选择两种不同标记图案之间的线条?可能有多个部分标有这些模式。
例如: 假设文件包含:
abc
def1
ghi1
jkl1
mno
abc
def2
ghi2
jkl2
mno
pqr
stu
起始模式为abc
,结束模式为mno
所以,我需要输出为:
def1
ghi1
jkl1
def2
ghi2
jkl2
我使用sed匹配模式一次:
sed -e '1,/abc/d' -e '/mno/,$d' <FILE>
sed
或awk
有没有办法在文件结束前反复执行此操作?
答案 0 :(得分:170)
使用带有标记的awk
可在必要时触发打印:
$ awk '/abc/{flag=1;next}/mno/{flag=0}flag' file
def1
ghi1
jkl1
def2
ghi2
jkl2
这是如何运作的?
/abc/
匹配包含此文字的行,以及/mno/
。 /abc/{flag=1;next}
时,flag
设置abc
。然后,它跳过了这条线。 /mno/{flag=0}
后,flag
取消设置mno
。flag
是一个默认操作的模式,即print $0
:如果flag
等于1,则会打印该行。有关更详细的说明和示例,以及模式显示与否的情况,请参阅How to select lines between two patterns?。
答案 1 :(得分:40)
使用sed
:
sed -n -e '/^abc$/,/^mno$/{ /^abc$/d; /^mno$/d; p; }'
-n
选项表示默认情况下不打印。
该模式会查找仅包含abc
到mno
的行,然后执行{ ... }
中的操作。第一个操作会删除abc
行;第二个是mno
行;并且p
打印剩余的行。您可以根据需要放松正则表达式。 <{1}} .. abc
范围之外的任何行都不会被打印出来。
答案 2 :(得分:17)
这可能适合你(GNU sed):
sed '/^abc$/,/^mno$/{//!b};d' file
删除除abc
和mno
答案 3 :(得分:13)
sed '/^abc$/,/^mno$/!d;//d' file
比ppotong's {//!b};d
空的正斜杠//
表示:&#34;重复使用的最后一个正则表达式&#34;。并且命令的作用与更易理解的相同:
sed '/^abc$/,/^mno$/!d;/^abc$/d;/^mno$/d' file
如果RE为空(即,未指定模式),则sed的行为应如同指定最后一个命令中使用的最后一个RE(作为地址或作为替换命令的一部分)。
答案 4 :(得分:5)
从之前的响应链接中,在Solaris上运行ksh的那个链接就是:
require(dplyr)
require(ggplot2)
bp <- ggplot(data=PlantGrowth %>% group_by(group) %>% mutate(group2=paste(group,length(group))) %>%
ungroup(), aes(x=group, y=weight, fill=group2)) + geom_violin() +
geom_dotplot(binaxis='y', stackdir='center', dotsize=0.5, binwidth = 0.01) +
stat_summary(fun.data = give.sample.size, geom = "text")
答案 5 :(得分:2)
perl -lne 'print if((/abc/../mno/) && !(/abc/||/mno/))' your_file
答案 6 :(得分:2)
Don_crissti的答案来自Show only text between 2 matching pattern?
firstmatch="abc"
secondmatch="cdf"
sed "/$firstmatch/,/$secondmatch/!d;//d" infile
比AWK的应用程序效率更高,请参阅here。
答案 7 :(得分:1)
file.awk:
BEGIN {
record=0
}
/^abc$/ {
record=1
}
/^mno$/ {
record=0;
print "s="s;
s=""
}
!/^abc|mno$/ {
if (record==1) {
s = s"\n"$0
}
}
使用:awk -f file.awk data
...
编辑:O_o fedorqui解决方案比我的更好/更漂亮。
答案 8 :(得分:0)
我尝试使用awk
在两个图案之间打印行,而 pattern2也匹配pattern1 。并且pattern1线也应该被打印。
例如 来源
package AAA
aaa
bbb
ccc
package BBB
ddd
eee
package CCC
fff
ggg
hhh
iii
package DDD
jjj
应该有一个输出
package BBB
ddd
eee
其中pattern1为package BBB
,pattern2为package \w*
。请注意,CCC
不是一个已知值,因此无法进行字面匹配。
在这种情况下,@ scai的awk '/abc/{a=1}/mno/{print;a=0}a' file
和@fedorqui的awk '/abc/{a=1} a; /mno/{a=0}' file
都不适合我。
最后,我设法通过awk '/package BBB/{flag=1;print;next}/package \w*/{flag=0}flag' file
解决了问题,哈哈
awk '/package BBB/{flag=1;print;next}flag;/package \w*/{flag=0}' file
会花费更多的精力来打印pattern2行,即
package BBB
ddd
eee
package CCC
答案 9 :(得分:0)
这也可以通过对标志进行逻辑运算和递增/递减运算来完成:
awk '/mno/&&--f||f||/abc/&&f++' file