简体   繁体   中英

Using sed to match a pattern and deleting from the line to the end of the file

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):

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 (eg GNU-specific) options.

The actual text can be found here: http://pastebin.com/CYBbJ3qr Note the change from -----THIS STUFF IS USELESS----- to -----BEGIN PGP SIGNATURE----- .

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

sed '/^-----THIS STUFF IS USELESS-----$/Q' file

where Q is similar to q quit command, but doesn't print the matching line

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.

sed -e '/^-----THIS STUFF IS USELESS-----$/,$ d'

脏工具刀grep版本:

cat your_output.txt | grep -B 99999999 "THIS STUFF IS USELESS" | grep -v "THIS STUFF IS USELESS"

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.

Demo+explanation: http://regex101.com/r/xF2fN5

You only need to run this one expression.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM