Linux 使用 sed 匹配模式并从行到文件末尾删除
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14046878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using sed to match a pattern and deleting from the line to the end of the file
提问by Albert H
I'm trying to match a pattern from piped input and/or a file, and then remove from the matched lines to the end of the file, inclusive. I've looked everywhere, but can't seem to find an expression that would fit my needs.
我试图匹配来自管道输入和/或文件的模式,然后从匹配的行中删除到文件末尾,包括在内。我到处找,但似乎找不到适合我需要的表达方式。
The following expression allows me to remove to the beginning of the stream, including the matched pattern:
以下表达式允许我删除到流的开头,包括匹配的模式:
sed -e '1,/Files:/d'
Given some sample data:
给定一些样本数据:
Blah blah blah
Foobar foo foo
Files:
somefiles.tar.gz 1 2 3
somefiles.tar.gz 1 2 3
-----THIS STUFF IS USELESS-----
BLEH BLEH BLEH
BLEH BLEH BLEH
Running the above expression produces:
运行上面的表达式会产生:
Files:
somefiles.tar.gz 1 2 3
somefiles.tar.gz 1 2 3
-----THIS STUFF IS USELESS-----
BLEH BLEH BLEH
BLEH BLEH BLEH
I would like to achieve a similar effect, but in the opposite direction. Using the output from the previous expression, I want to remove from -----THIS STUFF IS USELESS-----
to the end of the file, inclusive. It should produce (after going through the first expression):
我想达到类似的效果,但方向相反。使用上一个表达式的输出,我想从-----THIS STUFF IS USELESS-----
文件的末尾删除,包括。它应该产生(经过第一个表达式后):
Files:
somefiles.tar.gz 1 2 3
somefiles.tar.gz 1 2 3
I'm also open to using any other tools, as long as it is available on any other POSIX system and does not use version specific (e.g. GNU-specific) options.
我也愿意使用任何其他工具,只要它在任何其他 POSIX 系统上可用并且不使用特定于版本(例如特定于 GNU)的选项。
The actual text can be found here: http://pastebin.com/CYBbJ3qrNote the change from -----THIS STUFF IS USELESS-----
to -----BEGIN PGP SIGNATURE-----
.
可以在此处找到实际文本:http: //pastebin.com/CYBbJ3qr请注意从-----THIS STUFF IS USELESS-----
到的更改-----BEGIN PGP SIGNATURE-----
。
采纳答案by shellter
why not
为什么不
sed '/^-----THIS STUFF IS USELESS-----$/,$d' file
In a range expression like you have used, ',$' will specify "to the end of the file"
在您使用的范围表达式中, ',$' 将指定“到文件末尾”
1 is first line in file,
$ is last line in file.
output
输出
Files:
somefiles.tar.gz 1 2 3
somefiles.tar.gz 1 2 3
With GNU sed
, you can do
有了GNU sed
,你可以做
sed '/^-----THIS STUFF IS USELESS-----$/Q' file
where Q
is similar to q
quit command, but doesn't print the matching line
whereQ
类似于q
退出命令,但不打印匹配的行
回答by Ed Morton
Instead of trying to figure out how to express what what you don't want, just print what you DO want:
不要试图弄清楚如何表达你不想要的东西,只需打印你想要的东西:
awk -v RS= '/Files:/' file
EDIT: Given your modified input:
编辑:鉴于您修改后的输入:
awk '/^Files:$/{f=1} f; /^$/{f=0}' file
or:
或者:
awk '/^Files:$/{f=1} f; /^-----THIS STUFF IS USELESS-----$/{f=0}' file
if you prefer.
若你宁可。
You can also use either of these:
您还可以使用以下任一方法:
awk '/^Files:$/,/^-----THIS STUFF IS USELESS-----$/' file
sed '/^Files:$/,/^-----THIS STUFF IS USELESS-----$/' file
but they are hard to extend later.
但是以后很难扩展。
回答by Firas Dib
Here's a regular expression that I think will do what you want it to: ^(?:(?!Files:).)+|\s*-----THIS STUFF IS USELESS-----.+
Make sure to set the dotall flag.
这是一个正则表达式,我认为它^(?:(?!Files:).)+|\s*-----THIS STUFF IS USELESS-----.+
可以满足您的要求:确保设置 dotall 标志。
Demo+explanation: http://regex101.com/r/xF2fN5
演示+说明:http: //regex101.com/r/xF2fN5
You only need to run this one expression.
你只需要运行这个表达式。
回答by Brad Lanam
sed -e '/^-----THIS STUFF IS USELESS-----$/,$ d'
回答by mVChr
Dirty utility knife grep
version:
脏美工刀grep
版:
cat your_output.txt | grep -B 99999999 "THIS STUFF IS USELESS" | grep -v "THIS STUFF IS USELESS"