Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use sed to return something from first line which matches and quit early?

Tags:

sed

I saw from

How to use sed to replace only the first occurrence in a file?

How to do most of what I want:

sed -n '0,/.*\(something\).*/s//\1/p'

This finds the first match of something and extracts it (of course my real example is more complicated). I know sed has a 'quit' command which will make it stop early, but I don't know how to combine the 'q' with the above line to get my desired behavior.

I've tried replacing the 'p' with {p;q;} as I've seen in some examples, but that is clearly not working.

like image 809
nosatalian Avatar asked Nov 20 '09 23:11

nosatalian


4 Answers

The "print and quit" trick works, if you also put the substitution command into the block (instead of only putting the print and quit there).

Try:

sed -n '/.*\(something\).*/{s//\1/p;q}'

Read this like: Match for the pattern given between the slashes. If this pattern is found, execute the actions specified in the block: Replace, print and exit. Typically, match- and substitution-patterns are equal, but this is not required, so the 's' command could also contain a different RE.

Actually, this is quite similar to what ghostdog74 answered for gawk.

like image 105
5 revs Avatar answered May 04 '23 01:05

5 revs


My specific use case was to find out via 'git log' on a git-p4 imported tree which perforce branch was used for the last commit. git log (when called without -n will log every commit that every happened (hundreds of thousands for me)).

We can't know a-priori what value to give git for '-n.' After posting this, I found my solution which was:

git log | sed -n '0,/.*\[git-p4:.*\/\/depot\/blah\/\([^\/]*\)\/.*/s//\1/p; /\[git-p4/ q' 

I'd still like to know how to do this with a non '/' separator, and without having to specify the 'git-p4' part twice, once for the extraction and once for the quit. There has got to be a way to combine both on the same line...

like image 23
nosatalian Avatar answered May 03 '23 23:05

nosatalian


Sed usually has an option to specify more than one pattern to execute (IIRC, it's the -e option). That way, you can specify a second pattern that quits after the first line.

Another approach is to use sed to extract the first line (sed '1q'), then pipe that to a second sed command (what you show above).

like image 27
David R Tribble Avatar answered May 04 '23 01:05

David R Tribble


use gawk

gawk '/MATCH/{
            print "do something with "$0
            exit 
}' file
like image 44
ghostdog74 Avatar answered May 04 '23 01:05

ghostdog74