'Print all lines between line containing a string and first blank line, starting with the line containing that string

I've tried awk:

awk -v RS="zuzu_mumu" '{print RS $0}' input_file > output_file

The obtained file is the exact input_file but now the first line in file is zuzu_mumu. How could be corrected my command?

After solved this, I've found the same string/patern in another arrangement; so I need to save all those records that match too, in an output file, following this rule:

  • if pattern match on a line, then look at previous lines and print the first line that follows an empty line, and print also the pattern match line and an empty line.

record 1

record 2

This is record 3 first line info 1 info 2 This is one matched zuzu_mumu line info 3 info 4 info 5

record 4

record 5

...

This is record n-1 first line info a This is one matched zuzu_mumu line info b info c

record n

...

I should obtain:

This is record 3 first line This is one matched zuzu_mumu line

This is record n-1 first line This is one matched zuzu_mumu line



Solution 1:[1]

Print all lines between line containing a string and first blank line, starting with the line containing that string

I would use GNU AWK for this task. Let file.txt content be

Able
Baker
Charlie

Dog
Easy
Fox

then

awk 'index($0,"aker"){p=1}p{if(/^$/){exit};print}' file.txt

output

Baker
Charlie

Explanation: use index String function which gives either position of aker in whole line ($0) or 0 and treat this as condition, so this is used like is aker inside line? Note that using index rather than regular expression means we do not have to care about characters with special meaning, like for example .. If it does set p value to 1. If p then if it is empty line (it matches start of line followed by end of line) terminate processing (exit); print whole line as is.

(tested in gawk 4.2.1)

Solution 2:[2]

If you don't want to match the same line again, you can record all lines in an array and print the valid lines in the END block.

awk '
f && /zuzu_mumu/ {              # If already found and found again
  delete ary; entries=1; next;  # Delete the array, reset entries and go to the next record
}
f || /zuzu_mumu/ {              # If already found or match the word or interest
  if(/^[[:blank:]]*$/){exit}    # If only spaces, exit
  f=1                           # Mark as found
  ary[entries++]=$0             # Add the current line to the array and increment the entry number
}
END {                             
  for (j=1; j<entries; j++)     # Loop and print the array values
      print ary[j]
}
' file

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Daweo
Solution 2 The fourth bird