I am trying to find a way to use awk to start printing only once it finds the search parameter and print only a couple of columns following it.

To try to explain a little better I am looking over a log file that prints a lot of information as a single line. I want to take and extrapolate only certain aspects of that line. IE there's a big file with this line somewhere in it:

blahblah blah blah there is a lot of information here for name: John Doe and it just keeps on going and doesn't stop.

I want it to search for name and only print out:

name: John Doe

I know I can use the column segment, but I don't actually know where in that line name will be in different files.

  • How will you be able to tell then, which word is the name? There might be multiple names, too, or no names on a line? – Alex Aug 25 '17 at 18:24
  • Why not use grep -o for this? grep -o 'name: ([A-Z][a-z]* )*' /path/to/input – DopeGhoti Aug 25 '17 at 18:29
  • There is always going to be a name listed somewhere within the file and inside of the long line of just dumped information from a database. It will also only contain one name as it is just the name for the individual database table. Ultimately, there is a lot of good information in these files that is just poorly formatted and I am trying to create a quick bash script I can run on those logs so that it is in a more reader friendly format. – Mike Mortimer Aug 25 '17 at 18:30
  • @DopeGhoti The point is, if he knows which name he's looking for, then he doesn't even have to search: he can just display it. His question is, how can he discern that single name from a lot of good information. I mean, will it always be prefixed by name:? – Alex Aug 25 '17 at 18:31
  • @Alex Yes, it's always going to be prefixed by name. I don't know what the name will be when I start looking though. – Mike Mortimer Aug 25 '17 at 18:34

The simplest answer would NOT involve awk. It would use grep, to output any matches of the word "name", and up to two words that follow:

grep -o 'name [A-Za-z]* [A-Za-z]*' filename

The -o switch includes only the parts that match, not the entire line; and the [A-Za-z]* tells that you are asking for a single word.

Let me know if you prefer to do this in awk-- but that would be much more complicated.

  • I'm glad-- I wasn't entirely sure whether this was what you wanted, from your post... – Alex Aug 25 '17 at 18:46
  • awk would not really be that much more complicated: awk /name [A-Z][a-z]* [A-Z][a-z]*/ { print substr( $0, RSTART, RLENGTH) }' inputfile. – DopeGhoti Aug 25 '17 at 19:22
  • @DopeGhoti Hmm, I wasn't aware of the / string / functionality. In fact, it doesn't seem to work on my machine... As your quote is written, it's a syntax error; if I add an opening single quote before /name, it yields no results; if I put the opening quote before { print, I get the error awk: non-terminated regular expression and... at source line 1 – Alex Aug 25 '17 at 19:49
  • I omitted what to search in.. the syntax is awk /regex/ ~ $0 { code to run if present } to search the entire line. – DopeGhoti Aug 25 '17 at 19:55
  • 1
    awk RSTART,RLENGTH works only for the explicit match(...) function as in DopeGhoti's separate answer but not for a regexp as a pattern or the ~ operator. – dave_thompson_085 Aug 26 '17 at 12:28

This can also be done with awk:

$ awk 'match( $0, /name [A-Z][a-z]* [A-Z][a-z]*/ ) { print substr( $0, RSTART, RLENGTH ) }' /path/to/inputfile

Perl solution:

perl -lne '/(name:\s+\w+\s+\w+)/ and print $1'

  • \s matches whitespace characters (whitespaces per see, tabulations, etc.)
  • \w matches letters and numbers
  • -lne means don't print anything (n), except when print is used, output a newline in the end (l) and execute (e) the following

So the whole line will match name: followed by one or more whitespace character and one or more letter, again one or more whitespace character and one or more letter, and will then print that.

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.