2

My file contains the data below:

tail fn0 logfile
more  tail3 fn0 logfile1
get than tail4 fn0 logfile2

I want to get output from the field before fn0 and the field after fn0.

Expected output:

tail logfile
tail3 logfile1
tail4 logfile2
5

You can use awk:

awk -v pattern="fn0" '{for (i=0;i<=NF;i++) {if ($i==pattern) print $(i-1),$(i+1) }}' file

or if you want to use a regex pattern:

awk -v pattern="^fn0$" '{for (i=0;i<=NF;i++) {if ($i~pattern) print $(i-1),$(i+1) }}' file

Output:

tail logfile
tail3 logfile1
tail4 logfile2
| improve this answer | |
3

With perl

$ perl -lane '($i) = grep {$F[$_] eq "fn0"} 0..$#F;
              print "$F[$i-1] $F[$i+1]"' ip.txt
tail logfile
tail3 logfile1
tail4 logfile2
  • -l will remove newline character from input line, and add it back while printing
  • -a split input line based on whitespaces, @F array will have the data
  • ($i) = grep {$F[$_] eq "fn0"} 0..$#F get index of the element whose exact content is fn0
  • print "$F[$i-1] $F[$i+1]" print the required fields


With sed that supports ERE

$ sed -E 's/^(.* )?([^ ]+) fn0 ([^ ]+).*/\2 \3/' ip.txt
tail logfile
tail3 logfile1
tail4 logfile2
  • ^(.* )? optional fields at start of line
  • ([^ ]+) fn0 ([^ ]+) capture fields before and after fn0 (assuming single space as field separator)
  • .* rest of the line
  • \2 \3 required fields in output
| improve this answer | |
0

a solution with grep and sed:

egrep -oh '[a-zA-Z0-9]+\ fn0\ [a-zA-Z0-9]+' testfile | sed 's/ fn0 / /'

| improve this answer | |
0
$ sed 's/.*\(tail[[:digit:]]*\) fn[[:digit:]]*/\1/' file
tail logfile
tail3 logfile1
tail4 logfile2

The sed expression is replaces everything on each line up to some substring matching tailXX fnYY with tailXX (where XX and YY are some positive integers).

| improve this answer | |

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.