awk -v dilema

Hello Folks,
How do I use awk for passing, seraching and returning certain lines above a pattern variable

 
numbers.txt
 
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen
fifteen
for text in ten thirteen sixteen
do
        awk -v wText="$text" '{a[++i]=$0;}/wText/{for(j=NR-4;j<=NR;j++)print a[j];}' numbers.txt > tmpfile
done

Output needed as below

six
seven
eight
nine
ten
 
nine
ten
eleven
twelve
thirteen
$ for text in ten thirteen sixteen; do awk -v wText="$text" '{a[++i]=$0} $0 ~ wText {for(j=NR-4; j<=NR; j++) {print a[j]} print "" }' number.txt; done
six
seven
eight
nine
ten

nine
ten
eleven
twelve
thirteen
1 Like

awk -f jv.awk numbers.txt where jv.awk is:

BEGIN {
  if (!pat) pat="ten thirteen sixteen"
  if (!lines) lines=4
  split(pat, tA, FS)
  for(i=1;i in tA;i++)
    patA[tA]
}
{ a[FNR]=$0 }
END {
  for(i=1;i<=FNR;i++)
    if (a in patA) {
       for(j=i-lines;j<=i;j++)
         print a[j]
       print ""
    }
}

or with specific strings to search:
awk -v pat='seven fifteen' -f jv.awk numbers.txt
or to get 4 lines above
awk -v pat='seven fifteen' -v lines=3 -f jv.awk numbers.txt

1 Like

On my linux box, I use:

grep -B4 teen numbers.txt

nine
ten
eleven
twelve
thirteen
fourteen
fifteen

-A option for "lines after"

Resolved.
Much appreciate your valuebale solutions.

Zaxxons solution fitted the best, altough vgresh99 solution is comparable.

quirkasaurus , your solution is good as well but works only if the string has "teen" in it.

Hi.

Compare egrep and cgrep :

#!/usr/bin/env bash

# @(#) s1	Demonstrate match with previous lines, allow overlap, cgrep.
# For cgrep, see:
# http://sourceforge.net/projects/cgrep/ verified Wed Sep  9 16:12:03 CDT 2015

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C egrep cgrep

FILE=${1-data1}

pl " Input data file $FILE:"
cat $FILE

pl " Results, egrep, do not expect separation of overlaps:"
egrep -B4 'ten|thirteen|sixteen' $FILE

pl " Results, cgrep, \"-o\" allows display of separate overlaps:"
cgrep -E -o -4 'ten|thirteen|sixteen' $FILE

exit 0

producing:

$ ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian 5.0.8 (lenny, workstation) 
bash GNU bash 3.2.39
egrep GNU grep 2.5.3
cgrep ATT cgrep 8.15

-----
 Input data file data1:
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen
fifteen

-----
 Results, egrep, do not expect separation of overlaps:
six
seven
eight
nine
ten
eleven
twelve
thirteen

-----
 Results, cgrep, "-o" allows display of separate overlaps:
========================================
six
seven
eight
nine
ten
========================================
nine
ten
eleven
twelve
thirteen

Best wishes ... cheers, drl