How to return specific text from a file based on its pattern?

Viewed 53

I have a file with several lines and would like to output a single word from it. e.g.

bla bla bla bla
WORD1 bla ldskjf sldfkj 0xksjdflksjflksjf

From this file, I would like to output only the word 0xksjdflksjflksjf. I am thinking of a command that would look for the line starting by WORD1 and then, looking for a word starting by 0x in this line.

I'm quite sure that awk or sed would allow me to do that. I found a way to do it but it doesn't very "clean":

awk '/^WORD1/ {print $5}'

It works but is there a better (e.g. based on the word pattern instead of its place in the line) way to do it?

3 Answers

If you have a file called 0x.txt with the following:

bla bla bla bla
WORD1 bla ldskjf sldfkj 0xksjdflksjflksjf
bla bla bla bla
WORD1 bla 0xksjdflksjflks ldskjf sldfkj

then:

awk '/^WORD1/ {for (i=1;i<=NF;i++) if ( match($i, /^0x/) ) print $i}' 0x.txt

will print what you need not depending on column number:

0xksjdflksjflksjf
0xksjdflksjflks

And a sed version (using GNU sed):

The input file:

cat file
bla bla bla bla
WORD1 bla ldskjf sldfkj 0xksjdflksjflksjf

Command execution:

sed -nr /^WORD1/{'s/^(WORD1.+)(0x\w+)(.*$)/\2/p}' file
0xksjdflksjflksjf

Suppressing normal output (-n), find lines beginning with WORD1, substitute everything up to 0x with nothing, then print the line.

I like the answer by @AlexZhu, but as an alternative without needing to iterate from 1 to NF using match() and then the RSTART and RLENGTH built-in variables set by match() along with substr(), e.g., using the same input file provided by @AlexZhu you would have:

awk '
    /^WORD1/ {
        match($0,/[ ]0x[^ ]+/)
        if (RLENGTH > -1)
            print substr ($0, RSTART+1, RLENGTH)
    }
' file
0xksjdflksjflksjf
0xksjdflksjflks

The documentation for each of the functions are contained in GNU Awk User's Guide.

Related