16

OS: Kernel 2.6.x

Utilities: From busybox 1.2x

A command outputs multiple lines of text.

string1 text1: "asdfs asdf adfas"
string2 text2: "iojksdfa kdfj adsfj;"
string3 text3: "skidslk sadfj"
string4 text4: "lkpird sdfd"
string5 text5: "alskjfdsd safsd"

Goal: I need to search for the line that contains "text4: " (no quotes) and then extract all characters after that string to the end of the line.

Desired Output: "lkpird sdfd" (with quotes)

Currently I have ...

command | grep 'text4:' | awk -F': ' '{print $3}'

Is there a simpler way to write this ?

24

Using sed

$ command | sed -n 's/.*text4://p'
 "lkpird sdfd"

-n tells sed not to print unless we explicitly ask it to. s/.*text4:// tells sed to remove any text from the beginning of the line to the final occurrence of text4:. If such a line is found, then the p tells sed to print it.

Using grep -P

$ command | grep -oP '(?<=text4:).*' 
 "lkpird sdfd"

-o tells grep to print only the matching part. (?<=text4:).* matches any text that follows text4: but does not include the text4:.

The -P option requires GNU grep. Thus, it will not work with busybox's builtin grep, nor with the default grep on BSD/Mac OSX systems.

Using awk

The original grep-awk solution can be simplified:

$ command | awk -F': ' '/text4: /{print $2}'
"lkpird sdfd"

Using awk (alternate)

$ command | awk '/text4:/{sub(/.*text4:/, ""); print}'
 "lkpird sdfd"

/text4:/ selects lines that contain text4:. sub(/.*text4:/, "") tells awk to remove all text from the beginning of the line to the last occurrence of text4: on the line. print tells awk to print those lines.

3
  • In the sed example, does the period specify the beginning of the line ?
    – uihdff
    Sep 23 '17 at 7:27
  • Added the space character after "text4:"
    – uihdff
    Sep 23 '17 at 7:33
  • 1
    @uihdff In regular expressions, . means any character and .* means zero or more of any characters. In sed, regular expressions match the left-most longest. That means that .*something will always match from the beginning of the line because that gives the left-most longest match. If you want to specify the beginning of a line anyway, use ^ as in ^.*something.
    – John1024
    Sep 23 '17 at 7:50
5

With grep and its PCRE support and \K notify.

command |grep -Po 'text4: \K.*'
2
  • 1
    Excellent answer. Unfortunately, I have to work with the functionality provided via busybox 1.25 which doesn't support the -P option.
    – uihdff
    Sep 23 '17 at 7:16
  • Sorry, I don't know busyBox doesn't have -P with grep, but you have great John's answer with sed and awk only Sep 23 '17 at 7:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.