Skip to main content
added 23 characters in body
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118
awk '/^ABC/ && pre { print dpre ORS $0; pre=""; next } { if(pre) print pre; pre=dpre=$0; sub(/ {0,4}/, "END ", dpre) } END{ if(pre) print dpre }' infile 
  • REPEAT
  • Read a line; Is it start with ABC (/^ABC/)?
    • no; then do nothing and next block will be executed; go to 2nd-Block
    • yes; Is pre was set?
      • yes, then do these
        • print content of the dpre variable then a single newline ORS and then current line itself
        • empty variable pre="" and jump to REPEAT because of next statement tell that.
      • no; then do nothing and next block will be executed; go to 2nd-Block
  • 2nd-Block
    • is pre was set?
      • yes; do these
        • print pre it's set in "if(pre) print pre";
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
      • no; do these
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
  • if END of file; print last state of the dpre variable if it was set, else jump to REPEAT.
  • finish
awk '/^ABC/ && pre { print dpre ORS $0; pre=""; next } { if(pre) print pre; pre=dpre=$0; sub(/ {0,4}/, "END ", dpre) } END{ print dpre }' infile 
  • REPEAT
  • Read a line; Is it start with ABC (/^ABC/)?
    • no; then do nothing and next block will be executed; go to 2nd-Block
    • yes; Is pre was set?
      • yes, then do these
        • print content of the dpre variable then a single newline ORS and then current line itself
        • empty variable pre="" and jump to REPEAT because of next statement tell that.
      • no; then do nothing and next block will be executed; go to 2nd-Block
  • 2nd-Block
    • is pre was set?
      • yes; do these
        • print pre it's set in "if(pre) print pre";
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
      • no; do these
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
  • if END of file; print last state of the dpre variable else jump to REPEAT.
  • finish
awk '/^ABC/ && pre { print dpre ORS $0; pre=""; next } { if(pre) print pre; pre=dpre=$0; sub(/ {0,4}/, "END ", dpre) } END{ if(pre) print dpre }' infile 
  • REPEAT
  • Read a line; Is it start with ABC (/^ABC/)?
    • no; then do nothing and next block will be executed; go to 2nd-Block
    • yes; Is pre was set?
      • yes, then do these
        • print content of the dpre variable then a single newline ORS and then current line itself
        • empty variable pre="" and jump to REPEAT because of next statement tell that.
      • no; then do nothing and next block will be executed; go to 2nd-Block
  • 2nd-Block
    • is pre was set?
      • yes; do these
        • print pre it's set in "if(pre) print pre";
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
      • no; do these
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
  • if END of file; print last state of the dpre variable if it was set, else jump to REPEAT.
  • finish
added 368 characters in body
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118
awk '/^ABC/ && pre { print "END" dpre ORS $0; pre=""; next } { if(pre) print pre; pre=dpre=$0; sub(/[[:blank:]]+ {0,4}/," "END ", dpre) } END{ print "END" dpre }' infile 

first block will be executed only if a line starts with ABC string and when a temporary variable pre also was set otherwise next block will be executed.

  • if there was things inside pre print it first if(pre) print pre (with this we delay printing of previous line in order to check if next line starts with ABC or not, because we need to add END in front of that line)

    if there was things inside pre print it first if(pre) print pre (with this we delay printing of previous line in order to check if next line starts with ABC or not, because we need to add END in front of that line)

  • then we copy that line into say two separate variables pre and dpre (one would be untouched (later we need print it untouched) and another we will update for formatting purposes and then print, so with sub(/[[:blank:]]+/," ", dpre) we replace all leading whitespaces (if any) in dpre into only 3 space characters to align formatting).

    then we copy that line into say two separate variables pre and dpre (one would be untouched (later we need print it untouched) and for the another one in sub(/ {0,3}/,"END ", dpre) we are prepending the END string into dpre.

    Note that with {0,4} (zero or maximum 4 spaces; 4 is obtained from the length of END<SPC>) we ensure that the END string will be always prepended as well as preventing truncating the original line value if there was no spaces at all.

 

now we are at processingBelow you can trace each iteration of the first line ABC, the variables value are as following:

pre=ABC dpre=ABC 

then next line will be read i,ecommand for your own understanding: 2 3 4;

  • REPEAT

    REPEAT
  • is it start with /^ABC/?

    Read a line; Is it start with ABC (/^ABC/)?
    • no, so execute next block as follow

      no; then do nothing and next block will be executed; go to 2nd-Block
    • yes; Is pre was set?
      • is pre set? yes, print it then "if(pre) print pre" and ABC will be printed.

        yes, then do these
      • updated the pre and dpre with current line which is 2 3 4.

        • print content of the dpre variable then a single newline ORS and then current line itself
        • empty variable pre="" and jump to REPEAT because of next statement tell that.
      • replace leading whitespace to 3 spaces in dpre; now those are contains:

        pre= 2 3 4 dpre= 2 3 4 
        no; then do nothing and next block will be executed; go to 2nd-Block
  • 2nd-Block
    • yes, then do these:

      is pre was set?
      • print "END" then content of the dpre variable then a signle newline ORS and then current line itselfyes; do these
        • print pre it's set in "if(pre) print pre";
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
      • empty pre variable pre="" and jump to REPEATno and read next line.; do these
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
  • read next line and jump to REPEAT

    if END of file; print last state of the dpre variable else jump to REPEAT.
  • finish
awk '/^ABC/ && pre { print "END" dpre ORS $0; pre=""; next } { if(pre) print pre; pre=dpre=$0; sub(/[[:blank:]]+/," ", dpre) } END{ print "END" dpre }' infile 

first block will be executed only if a line starts with ABC string and when a temporary variable pre was set otherwise next block will be executed.

  • if there was things inside pre print it first if(pre) print pre (with this we delay printing of previous line in order to check if next line starts with ABC or not, because we need to add END in front of that line)
  • then we copy that line into say two separate variables pre and dpre (one would be untouched (later we need print it untouched) and another we will update for formatting purposes and then print, so with sub(/[[:blank:]]+/," ", dpre) we replace all leading whitespaces (if any) in dpre into only 3 space characters to align formatting).

now we are at processing of the first line ABC, the variables value are as following:

pre=ABC dpre=ABC 

then next line will be read i,e: 2 3 4;

  • REPEAT

  • is it start with /^ABC/?

    • no, so execute next block as follow

      • is pre set? yes, print it then "if(pre) print pre" and ABC will be printed.

      • updated the pre and dpre with current line which is 2 3 4.

      • replace leading whitespace to 3 spaces in dpre; now those are contains:

        pre= 2 3 4 dpre= 2 3 4 
    • yes, then do these:

      • print "END" then content of the dpre variable then a signle newline ORS and then current line itself
      • empty pre variable pre="" and jump to REPEAT and read next line.
  • read next line and jump to REPEAT

awk '/^ABC/ && pre { print dpre ORS $0; pre=""; next } { if(pre) print pre; pre=dpre=$0; sub(/ {0,4}/, "END ", dpre) } END{ print dpre }' infile 

first block will be executed only if a line starts with ABC string and when a temporary variable pre also was set otherwise next block will be executed.

  • if there was things inside pre print it first if(pre) print pre (with this we delay printing of previous line in order to check if next line starts with ABC or not, because we need to add END in front of that line)

  • then we copy that line into say two separate variables pre and dpre (one would be untouched (later we need print it untouched) and for the another one in sub(/ {0,3}/,"END ", dpre) we are prepending the END string into dpre.

    Note that with {0,4} (zero or maximum 4 spaces; 4 is obtained from the length of END<SPC>) we ensure that the END string will be always prepended as well as preventing truncating the original line value if there was no spaces at all.

 

Below you can trace each iteration of the command for your own understanding:

  • REPEAT
  • Read a line; Is it start with ABC (/^ABC/)?
    • no; then do nothing and next block will be executed; go to 2nd-Block
    • yes; Is pre was set?
      • yes, then do these
        • print content of the dpre variable then a single newline ORS and then current line itself
        • empty variable pre="" and jump to REPEAT because of next statement tell that.
      • no; then do nothing and next block will be executed; go to 2nd-Block
  • 2nd-Block
    • is pre was set?
      • yes; do these
        • print pre it's set in "if(pre) print pre";
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
      • no; do these
        • update current line into both variables pre=dpre=$0;
        • prepend END string for dpre.
  • if END of file; print last state of the dpre variable else jump to REPEAT.
  • finish
added 39 characters in body
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118
awk '/^ABC/ && pre { print "END" dpre ORS $0; pre=""; n=0; next } { if(npre) print pre; n=1; pre=dpre=$0; sub(/[[:blank:]]+/," ", dpre) } END{ print "END" dpre }' infile 

first block will be executed only if a line starts with ABC string and when a temporary variable pre was set otherwise next block will be executed.

the END{...} block will be executed only once and after end of all.

for the first line of course still pre variable doesn't set yet, so second block will be executed and it does following:

  • if there was things inside pre print it first if(pre) print pre (with this we delay printing of previous line in order to check if next line starts with ABC or not, because we need to add END in front of that line)
  • then we copy that line into say two separate variables pre and dpre (one would be untouched (later we need print it untouched) and another we will update for formatting purposes and then print, so with sub(/[[:blank:]]+/," ", dpre) we replace all leading whitespaces (if any) in dpre into only 3 space characters to align formatting).

now we are at processing of the first line ABC, the variables value are as following:

pre=ABC dpre=ABC 

then next line will be read i,e: 2 3 4;

  • REPEAT

  • is it start with /^ABC/?

    • no, so execute next block as follow

      • is pre set? yes, print it then "if(pre) print pre" and ABC will be printed.

      • updated the pre and dpre with current line which is 2 3 4.

      • replace leading whitespace to 3 spaces in dpre; now those are contains:

        pre= 2 3 4 dpre= 2 3 4 
    • yes, then do these:

      • print "END" then content of the dpre variable then a signle newline ORS and then current line itself
      • empty pre variable pre="" and jump to REPEAT and read next line.
  • read next line and jump to REPEAT

awk '/^ABC/ && pre { print "END" dpre ORS $0; pre=""; n=0; next } { if(n) print pre; n=1; pre=dpre=$0; sub(/[[:blank:]]+/," ", dpre) } END{ print "END" dpre }' infile 
awk '/^ABC/ && pre { print "END" dpre ORS $0; pre=""; next } { if(pre) print pre; pre=dpre=$0; sub(/[[:blank:]]+/," ", dpre) } END{ print "END" dpre }' infile 

first block will be executed only if a line starts with ABC string and when a temporary variable pre was set otherwise next block will be executed.

the END{...} block will be executed only once and after end of all.

for the first line of course still pre variable doesn't set yet, so second block will be executed and it does following:

  • if there was things inside pre print it first if(pre) print pre (with this we delay printing of previous line in order to check if next line starts with ABC or not, because we need to add END in front of that line)
  • then we copy that line into say two separate variables pre and dpre (one would be untouched (later we need print it untouched) and another we will update for formatting purposes and then print, so with sub(/[[:blank:]]+/," ", dpre) we replace all leading whitespaces (if any) in dpre into only 3 space characters to align formatting).

now we are at processing of the first line ABC, the variables value are as following:

pre=ABC dpre=ABC 

then next line will be read i,e: 2 3 4;

  • REPEAT

  • is it start with /^ABC/?

    • no, so execute next block as follow

      • is pre set? yes, print it then "if(pre) print pre" and ABC will be printed.

      • updated the pre and dpre with current line which is 2 3 4.

      • replace leading whitespace to 3 spaces in dpre; now those are contains:

        pre= 2 3 4 dpre= 2 3 4 
    • yes, then do these:

      • print "END" then content of the dpre variable then a signle newline ORS and then current line itself
      • empty pre variable pre="" and jump to REPEAT and read next line.
  • read next line and jump to REPEAT

added 39 characters in body
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118
Loading
Post Undeleted by αғsнιη
added 41 characters in body
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118
Loading
Post Deleted by αғsнιη
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118
Loading