foo
I love
Stack Exchange
bar
Some junk
lines
foo
Welcome to the
world of
Bash
bar
foo
Elon Musk
rocks
是的,文件末尾没有bar
补码foo
所需的输出是
I love Stack Exchange
Welcome to the world of Bash
Elon Musk rocks
因此,删除所有换行符,在^foo
and之间^bar
或在^foo
and之间,end of file
其中没有bar
答案1
和awk
:
awk '
$0 == "foo" {if (sep) print ""; sep = ""; inside = 1; next}
$0 == "bar" {inside = 0; next}
inside {printf "%s", sep $0; sep = " "}
END {if (sep) print ""}'
要匹配foo
第一个单词为 的行,请替换$0 == "foo"
为$1 == "foo"
;要匹配以 开头的行foo
,请替换为/^foo/
( 的缩写$0 ~ /^foo/
)。
答案2
Perl 来救援!
perl -ne '
if ($e = /^foo$/ .. /^bar$/) {
if ($e =~ /E/) { print "\n" }
else {
chomp;
print " " if $e > 2;
print if $e > 1;
}
}' -- input.txt
-n
逐行读取输入..
是范围运算符,它返回块中每一行的相对行号。最后一行已E0
附加到其上。
答案3
你也可以这样做:
a) 这是POSIX-sed
兼容的代码,其中我们将中范围线(!/foo/ 和 !/bar/)存储在保留区域中。
sed -e '
/foo/,/bar/!d
/foo/d
/bar/!{H;$!d;}
s/.*//;x;s/^\n//;y/\n/ /
' input-file.txt
b) 并Perl
如图所示
perl -lne '
next unless /foo/ ... /bar/;
push(@A, $_),next if !/foo/ && !/bar/ && !eof;
push(@A, $_) if !/foo/ && !/bar/ && eof;
print join " ", splice @A if /bar/ || !/foo/ && eof;
' input-file.txt
解释:
- 跳过不感兴趣的行或超出范围的行。范围定义为以包含 的行开始
/foo/
并以 结尾/bar/
,两者出现在不同的行上。 - 一旦我们进入范围,然后根据我们所在的线执行单独的操作。
- 对于不是 /foo/ 、 /bar/ 和 eof 的行:将该行存储在数组中
@A
。存储完成后,返回读取下一条记录(不是eof)。 - 仅对于范围的末尾,即
/bar/
或eof
,我们采取打印内容@A
并清空它的操作,为下一个收集周期做准备。