3

With this awk script I can print Nth line after match Pattern.

awk '/c&&!--c;/Pattern/{c=N}'

Now, I'm trying to print the line when matches Date and print the 3rd line after matches Time

echo "x
Date:2/19/2021
a
b
Time:
val:14:31:42
val:15:51:35
val:16:28:03
val:17:04:11
z
w" | 
awk '/Date/{d=$0} 
      c&&!--c;/Time/{print d " - "; c=3}'

Date:2/19/2021
val:16:28:03

The script prints what I want but in different line and I'd like to print the output in the same line like this

Date:2/19/2021  -  val:16:28:03

How can this be done? Thanks in advance

RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
Ger Cas
  • 2,188
  • 2
  • 18
  • 45

3 Answers3

4

Instead of print which always adds ORS, use printf instead:

echo "x
Date:2/19/2021
a
b
Time:
val:14:31:42
val:15:51:35
val:16:28:03
val:17:04:11
z
w" |  awk '/Date/{d=$0}
      c&&!--c;/Time/{printf d " - "; c=3}'

The first parameter passed to printf is the format string. If the format string contains a percent sign the whole thing will break because printf treats percent signs as special when they occur in the format string.

In your specific case the date will never have a percent sign, but if you use this method for printing other strings without a newline, you need to supply a format string separate from the parameter you are printing:

echo "x
Date:2/19/2021
a
b
Time:
val:14:31:42
val:15:51:35
val:16:28:03
val:17:04:11
z
w" |  awk '/Date/{d=$0}
      c&&!--c;/Time/{printf "%s - ", d; c=3}'
Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
  • 1
    There is no need for the `%s` – Aven Desta Feb 20 '21 at 02:59
  • Thanks so much. I'm not an expert but I've selected your answer because I see it easier. – Ger Cas Feb 20 '21 at 03:10
  • 5
    @AvenDesta if you're referring to `printf d` vs `printf "%s", d` - never do `printf whatever` for any user input as it'll fail cryypticall if/when the input contains printf formatting characters like `%s`, always do `printf "%s", whatever` instead. – Ed Morton Feb 20 '21 at 13:46
3

With your shown samples, please try following. Written and tested with shown samples in GNU awk. I have also used exit in case you are using an Input_file to read values from then in that case it will help.

your_variable | 
awk ' /^Date:/{val=$0;next} /^val/ && ++count==3{print val" - "$0;exit}'

With OP's way try:

your_variable | 
awk ' /^Date:/{val=$0;next} /^Time/{found=1;next} found && ++count==3{print val" - "$0;exit}'
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • Thanks for your solution. Is nice, but the 3rd line not always begins with `Val` or 1rst, 2nd, 3rd lines can have different texts. The unvariable string will always be the string `Time` and get the 3rd below of it. – Ger Cas Feb 20 '21 at 03:04
  • 1
    @GerCas, sure, already(few secs back or so) added your attempted code's improvement in answer, cheers :) – RavinderSingh13 Feb 20 '21 at 03:05
3

another similar one

... | awk '/Date/ {printf "%s - ",$0}
           /Time/ {c=4} 
           c&&!--c'
karakfa
  • 66,216
  • 7
  • 41
  • 56