How can I print all characters up to a specific pattern (with the exception of the pattern itself) using grep / awk / sed.

for instance

echo "abc-1234a :" | grep <do-something> 

to just print abc-1234a

+4
source share
1 answer

I think that they are closer to what you get, but not knowing what you are really trying to achieve, it's hard to say.

 echo "abc-1234a :" | egrep -o '^[^:]+' 

... although this will also correspond to lines that do not have a colon. If you only want colon strings, and you should only use grep, this might work:

 echo "abc-1234a :" | grep : | egrep -o '^[^:]+' 

Of course, this only makes sense if your echo "abc-1234a :" is an example that will replace perhaps a few lines of input.

The smallest tool you could use is probably cut :

 echo "abc-1234a :" | cut -d: -f1 

And sed always available ...

 echo "abc-1234a :" | sed 's/ *:.*//' 

For this last, if you only want to print lines containing a colon, change it to:

 echo "abc-1234a :" | sed -ne 's/ *:.*//p' 

Damn, you could do this in pure bash:

 while read line; do field="${line%%:*}" # do stuff with $field done <<<"abc-1234a :" 

For information on the %% bit, you can man bash and find "Parameter Extension".

UPDATE

You said:

These are the characters in the first line of input before the colon. input may contain several lines.

grep solutions are probably not your best bet, as they will also print data from subsequent lines, which may include colons. Of course, there are many ways to solve this requirement. We will start by entering a sample:

 $ function sample { printf "abc-1234a:foo\nbar baz:\nNarf\n"; } $ sample abc-1234a:foo bar baz: Narf 

You can use several channels, for example:

 $ sample | head -1 | grep -Eo '^[^:]*' abc-1234a $ sample | head -1 | cut -d: -f1 abc-1234a 

Or you can use sed to process only the first line:

 $ sample | sed -ne '1s/:.*//p' abc-1234a 

Or tell sed to exit after printing the first line (which is faster than reading the whole file):

 $ sample | sed 's/:.*//;q' abc-1234a 

Or do the same, but show the result only if the colon was found (for security):

 $ sample | sed -ne 's/:.*//p;q' abc-1234a 

Or try awk to do the same (as the last 3 examples, respectively):

 $ sample | awk '{sub(/:.*/,"")} NR==1' abc-1234a $ sample | awk 'NR>1{nextfile} {sub(/:.*/,"")} 1' abc-1234a $ sample | awk 'NR>1{nextfile} sub(/:.*/,"")' abc-1234a 

Or in bash, without pipes at all:

 $ read line < <(sample) $ printf '%s\n' "${line%%:*}" abc-1234a 
+12
source

Source: https://habr.com/ru/post/1433487/


All Articles