我有这些数据:
One
two
three
Four
five
six
Seven
eight
这个命令:
sed -n '/^Four$/,/^[^[:blank:]]/p'
我得到以下输出:
Four
five
six
Seven
如何更改此sed表达式与输出的最后一行不匹配?所以理想的输出应该是:
Four
five
six
我尝试了很多涉及感叹号的事情,但还没有成功地接近这个问题。
答案 0 :(得分:7)
使用“do..while()”循环:
sed -n '/^Four$/{:a;p;n;/^[[:blank:]]/ba}'
细节:
/^Four$/ {
:a # define the label "a"
p # print the pattern-space
n # load the next line in the pattern space
/^[[:blank:]]/ba # if the pattern succeeds, go to label "a"
}
答案 1 :(得分:4)
你可以管道到另一个sed
并跳过最后一行:
sed -n '/^Four$/,/^[^[:blank:]]/p' file | sed '$d'
Four
five
six
或者您可以使用:
sed -n '/^Four$/,/^[^[:blank:]]/{/^Four$/p; /^[^[:blank:]]/!p;}' file
答案 2 :(得分:2)
您使用了错误的工具。 sed是做s / old / new,就是这样。只需使用awk:
$ awk '/^[^[:blank:]]/{f=/^Four$/} f' file
Four
five
six
工作原理:每次找到一个不以空格开头的行(/^[^[:blank:]]/
)时,它会设置一个标记f
(对于"找到")如果该行以Four
开头,则为0,否则为{f=/^Four$/
)。每当f
非零时被解释为真实条件,因此调用awks默认行为,即打印当前行。因此,当它遇到以Four开头的块时,它会打印该块中的每一行,因为f
是1 / true,而对于其他每个块,它都不打印,因为f
是0 / false。 / p>
答案 3 :(得分:1)
关注awk
可能会对您有所帮助。
awk '!/^ /{flag=""} /Four/{flag=1} flag' Input_file
输出如下。
Four
five
six
如果您需要将输出保存到Input_file本身,请将> temp_file && mv temp_file Input_file
附加到上面的代码中。
答案 4 :(得分:0)
grep -Pzo '\n\KFour\n(\s.+\n)+' input.txt
<强>输出强>
Four
five
six
答案 5 :(得分:0)
这可能适合你(GNU sed):
sed '/^Four/{:a;n;/^\s/ba};d' file
如果该行以Four
开头,则打印它以及以空格开头的任何后续行。
另一种方式:
sed '/^\S/h;G;/^Four/MP;d' file
如果一行以非空格开头,请将其复制到保留空间(HS)。将HS附加到每一行,如果任一行以Four
开头,则打印第一行并删除其余行。这将删除除Four
开头的部分以外的所有行。