我想使用像这样的sed脚本
#n
/^TODO/,/^$/p
除了sed应该在遇到两个连续的空行后停止打印范围,而不是仅仅一个空白行。然后它应该继续扫描下一个感兴趣的范围。换句话说,感兴趣范围的结束由两个空行定义。我甚至不确定地址范围是否可以处理这种要求,所以如果还有其他方法可以解决这个问题,请告诉我。
答案 0 :(得分:6)
当遇到两个连续的空白行时,无论空白行与非空行的奇数/偶数配对如何,这都应该停止:
不要打印两个空行:
sed -n 'N;/^\n$/q;P;D'
打印其中一个:
sed -n 'N;/^\n$/{P;q};P;D'
打印两者:
sed -n 'N;/^\n$/{p;q};P;D'
修改强>
以下是你如何在你的范围内完成这项工作:
sed -n '/^TODO/,${N;/^\n$/q;P;D}'
编辑2:
每 dan的(OP)评论和编辑的要求,这似乎可以找到一个范围内的模式,该范围以两个空白行结尾,在文件中多次:
sed -n '/^TODO/,/^$/{H;N;/^\n$/{b};p}'
答案 1 :(得分:1)
使用sed进行简单替换。
$ more file
1
2
blah blah
TODO
blah blah
4
5
6
7
8
9
10
11
end
$ awk -vRS="\n\n" '/TODO/{print;exit}' file
1
2
blah blah
TODO
blah blah
4
5
答案 2 :(得分:1)
相反,寻找TODO块的开始,然后循环直到找到一对空白行。
这是一个测试文件。之后是对一些提议的解决方案的比较。
cat >tricky_todo.txt <<EOF
TODO block 1 line 1 (last line)
THIS LINE SHOULDN'T BE PRINTED #1
THIS LINE SHOULDN'T BE PRINTED #2
TODO block 2 line 1
block 2 line 2
block 2 line 3
block 2 line 4
block 2 line 6
block 2 line 7
block 2 line 8 (last line)
TODO block 3 line 1
block 3 line 2
block 3 line 3
block 3 line 4
block 3 line 5 (last line)
TODO block 4 line 1
block 4 line 2
block 4 line 3
block 4 line 4
block 4 line 5 (last line)
THIS LINE SHOULDN'T BE PRINTED #3
THIS LINE SHOULDN'T BE PRINTED #4
EOF
不幸的是,获得地址范围来完成此任务几乎是不可能的。多余的行太多,而不是所有所需的行:-(
sed -n '/^TODO/,/^$/{H;N;/^\n$/{b};p}' <tricky_todo.txt
TODO block 1 line 1 (last line)
THIS LINE SHOULDN'T BE PRINTED #1
TODO block 2 line 1
block 2 line 2
block 2 line 3
block 2 line 4
block 2 line 6
TODO block 3 line 1
block 3 line 2
block 3 line 3
block 3 line 4
block 3 line 5 (last line)
TODO block 4 line 1
注意::如果TODO块是文件中的最后一个内容,则它必须以OP中指定的两个空行结尾,否则它将被删除。 / p>
sed -n '/^TODO/{:a;N;s/\n\n$//;Ta;p}' <tricky_todo.txt
TODO block 1 line 1 (last line)
TODO block 2 line 1
block 2 line 2
block 2 line 3
block 2 line 4
block 2 line 6
block 2 line 7
block 2 line 8 (last line)
TODO block 3 line 1
block 3 line 2
block 3 line 3
block 3 line 4
block 3 line 5 (last line)
TODO block 4 line 1
block 4 line 2
block 4 line 3
block 4 line 4
block 4 line 5 (last line)
FWIW,当我想到上面的脚本时,我以某种方式忽略了potong的原始答案(有一个小缺陷)。当我提到它时,potong使用其他策略完全重写了该答案。由于这个原因和我脚本的警告,我将在此处包括potong原始答案的更正版本:
sed '/^TODO/!d;:a;$!{N;s/\n\n$//;t;ba}' <tricky_todo.txt
Awk当然功能强大,但是我个人倾向于使用sed,因为它更像是我每天使用的心爱的vi。不过,我们开始:
awk -vRS="\n\n\n" -vFS="\n" '/TODO/{s=0;for(n=1;n<=NF;n++){if(s==1||$n~/^TODO/){print $n;s=1}}}' <tricky_todo.txt
答案 3 :(得分:0)
sed 'N;/^\n$/q;P;D'
$ cat double_blank.txt foo bar baz blah one two three
$ sed 'N;/^\n$/q;P;D' double_blank.txt foo bar baz
答案 4 :(得分:0)
以SiegeX的答案为基础:
cat > lines <<'EOF'
a
c
d
EOF
sed '/^$/N; /^\n$/q' lines
答案 5 :(得分:0)
这可能对您有用:
sed '/^TODO/!d;:a;$!{N;s/\n$//;t;ba}' file