我可以打印文件 a 中的括号线
first
[
third
fourth
]
sixth
[
eighth
]
tenth
通过做
% <a sed -n '/\[/,/\]/p'
打印
[
third
fourth
]
[
eighth
]
但是如果我只想要第二场比赛呢?最后三行?
答案1
更容易使用,假设由和awk
定义的块本身不包含该块或位于该块内[
]
[
]
$ awk -v b=2 '/\[/{c++} c==b; /]/ && c==b{exit}' ip.txt
[
eighth
]
-v b=2
变量来指定需要哪个块/\[/{c++}
如果行匹配起始条件则增加计数器c==b;
如果计数器等于所需的块,则打印输入记录/]/ && c==b{exit}
匹配结束条件时退出
另一种写法:
awk -v b=2 '/\[/{c++} c==b{print $0; if(/]/) exit}' ip.txt
答案2
$ sed -n '/^\[/h; /^\[/,/^\]/H; ${x;s/^\[\n//;p;}' file
[
eighth
]
带注释的sed
脚本(假设-n
):
/^\[/h; # replace hold space with this line
/^\[/,/^\]/H; # append these lines to hold space with embedded newlines
${ # at last line of input
x; # swap in the hold space
s/^\[\n//; # delete the first "[" and the newline following it
p; # print
}
也就是说,每当我们找到以 开头的行时[
,就通过复制该行来清除保留空间。然后继续将行追加到保留空间,直到找到以 开头的相应行]
。
最后,我们将有一个[
过多的保留空间,因此在打印数据之前删除该空间(以及其后嵌入的换行符)。
答案3
使用sed
编辑器,我们可以执行如下操作:
sed -ne ' ;# "-n" suppresses autoprint of pattern space
/^\[/!d ;# skip lines that donot begin a fresh block
:a;$!N;/\n]/!ba ;# keep appending lines to pattern space until end of block
G ;# append our makeshift counter (hold space) to pattern spc
s/\n\{2\}$//p ;# only when counter had 2 chars in it, we print block
/\n$/!q ;# target block, 2nd block has been printed so quit
x;s/$/\n/;x ;# target block not reached, so increment
' input.file
对于Perl
,我们可以将该...
运算符与布尔值 $k == 2 一起使用,表明我们已经到达了预期的目标块并且需要打印它。
perl -lne 'print if /^\[/ && ++$k == 2 ... /^]/' input.file
答案4
nl -bp'\[' -s ' ' input.txt | sed -n '/ *2 \[/,/\]/p' | cut -c 8-
输入.txt:
first
[
third
fourth
]
sixth
[
eighth
]
tenth
标准输出:
[
eighth
]
解释
nl -bp
可以根据特定模式添加行号。- 这里我们使用空格作为分隔符而不是制表符,
nl -s ' '
因为\t
在sed
.
nl -bp'\[' -s ' ' input.txt
first
1 [
third
fourth
]
sixth
2 [
eighth
]
tenth
- 默认情况下,
nl
在前面添加 6 个字符进行填充,您可以通过 删除前 7 个字符cut -c 8-
。