AWK to find desire lines and merge them

Viewed 86

Found easiest solution sofar to extract 3rd and 5th line after pattern (searching huge error logs)
but output I got is 2 lines and I want them merged.
Please advice.

Sample:

pattern
1st line  
2nd line  
3rd line  
4th line  
5th line
pattern 2
1st line after second pattern
2nd line after second pattern 
3rd line after second pattern 
4th line after second pattern 
5th line after second pattern

using :

awk '/pattern/ {nr[NR+3]; nr[NR+5]}; NR in nr'

I got

3rd line  
5th line
3rd line after second pattern 
5th line after second pattern

But how to get:

3rd line 5th line
3rd line after second pattern 5th line after second pattern

Thank you

6 Answers

Use paste like so:

awk '/pattern/ {nr[NR+3]; nr[NR+5]}; NR in nr' in_file | paste -d' ' - -

You may use this awk:

awk '/^pattern/ {n=NR} NR == n+3 {printf "%s ", $0} NR == n+5' file

3rd line 5th line
3rd line after second pattern 5th line after second pattern

Using sed (if an option)

$ sed -n '/^pattern/{n;n;n;h;n;n;x;G;s/\n//p}' input_file
3rd line  5th line
3rd line after second pattern 5th line after second pattern

Guessing at what you mean by "pattern" (see How do I find the text that matches a pattern?):

$ cat tst.awk
/^pattern/ {
    printf "%s", ors
    delete nrs
    nrs[NR+3]
    nrs[NR+5]
    ofs = ""
    ors = ORS
}
NR in nrs {
    printf "%s%s", ofs, $0
    ofs = OFS
}
END {
    printf "%s", ors
}

$ awk -f tst.awk file
3rd line 5th line
3rd line after second pattern 5th line after second pattern
{m,g}awk '
BEGIN { _="^"(_="[ \t]+")"|"(_)"$"
    FS = "pattern"
} $!NF = NF<=!+_ ? __ : sprintf("%s %s",
            $(getline * getline * getline * gsub(_,__)*_),        
            $(          getline * getline * gsub(_,__)*_))'

.

3rd line 5th line
3rd line after second pattern 5th line after second pattern
awk -v r1="3" -v r2="5" '
   /^pattern$/ || /^pattern 2$/{i=0; p=$0; next}
   {i++; a[p][i] = $0} 
   END{for(e in a) print a[e][r1],a[e][r2]}
' input_file

3rd line 5th line
3rd line after second pattern 5th line after second pattern

awk -v r1="2" -v r2="4" ...

2nd line 4th line  
2nd line after second pattern 4th line after second pattern

Using a function

pasteRows(){
  local pattern1="$1"
  local pattern2="$2"
  local frow="$3"
  local srow="$4"

  awk -v pat1="$pattern1" -v pat2="$pattern2" -v r1="$frow" -v r2="$srow" '
   {    
        if($0 == pat1 || $0 == pat2) {i=0; p=$0; next}
        i++; a[p][i] = $0
   } 
   END{for(e in a) print a[e][r1],a[e][r2]}
  ' pattern.txt
}

$ pasteRows pattern "pattern 2" 3 5
3rd line 5th line
3rd line after second pattern 5th line after second pattern
$ pasteRows pattern "pattern 2" 1 4
1st line 4th line  
1st line after second pattern 4th line after second pattern
Related