2

I want to delete all the line between two patterns using basic awk or sed.

foo.txt :

----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

output.txt :

----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

I am using solaris 5.10, basic awk and sed only. The number of lines between 2 patterns may vary. Notice that the second string must be replaced but not the first string. Notice the difference between 2 patterns is the number of dashes. What you see in foo.txt is exactly what I have my real file.

1
 $ awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point

How it works

This script has one variable f. When f is true (1), we are in a range of lines to be deleted. When it is false (0), we are in a range that should be printed.

By default, f is false when the program starts.

  • !f{print}

    Print any line when f is false.

  • /----------------------/{f=!f;if (!f)print "Deleted up to this point"}

    If we reach the divider line, marked by dashes, then invert the value of f. If f is now false, then print the "deleted" message.

Update

The default awk on Solaris seems to have issues. Try:

nawk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

Or,

/usr/xpg4/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

Or,

/usr/xpg6/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

Answer for revised question

$ awk ' /^---------------------------------------------------  Cap in MB/{print "Deleted up to this point"; f=0; z=""; next;} /^----------------------------------------------------------------------  Cap in MB/{f=1; if(z)print substr(z,2); z=""; print;next;}  f{z=z"\n"$0;next;} END{print substr(z,2);}' foo.txt
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
| improve this answer | |
  • syntax error, bailing out near line 1 – ayrton_senna Jun 3 '15 at 22:12
  • @ayrton_senna I saw here a recommendation that solaris users should use /usr/bin/nawk or /usr/xpg4/bin/awk. Let me know if that helps. – John1024 Jun 3 '15 at 22:43
  • awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt awk: syntax error near line 1 awk: bailing out near line 1 May be my awk does't support your solution. I am using basic awk – ayrton_senna Jun 3 '15 at 22:45
  • @ayrton_senna Thanks. I also see here a report that nawk works better than awk on solaris. – John1024 Jun 3 '15 at 22:48
  • @ayrton_senna Also here is a recommendation to use nawk or /usr/xpg4/bin/awk or /usr/xpg6/bin/awk instead of awk on Solaris. – John1024 Jun 3 '15 at 22:50
1

Here's a simple solution with awk: turn off printing after the long dashed line, turn on printing after the short dashed line.

awk '
    !do_not_print {print}
    $0 == "----------------------------------------------------------------------  Cap in MB" {do_not_print = 1}
    $0 == "---------------------------------------------------  Cap in MB" {do_not_print = 0}
' <foo.txt >output.txt
| improve this answer | |
  • @Giles can you provide the command in a single line, im getting syntax error and bailing out near line 2 error – ayrton_senna Jun 3 '15 at 22:16
  • @ayrton_senna You can remove the newlines if you want. There's no syntax error, are you sure you copy-pasted the whole command (up to the last ')? Did you type this in a shell? Does it help if you use /usr/xpg4/bin/awk instead of /usr/bin/awk? – Gilles 'SO- stop being evil' Jun 3 '15 at 22:38
  • @Giles This i what i typed in awk '!do_not_print {print} $0 == "---------------------------------------------------------------------- Cap in MB" {do_not_print = 1} $0 == "--------------------------------------------------- Cap in MB" {do_not_print = 0}' foo.txt i am getting error – ayrton_senna Jun 3 '15 at 22:48
  • @ayrton_senna This is ok, so it must be a bug in your version of awk. Use /usr/xpg4/bin/awk instead of /usr/bin/awk, which is old and buggy. On Solaris, always put /usr/xpg4/bin ahead of /usr/bin in your PATH, unless you need to run legacy scripts that are over 20 years old. – Gilles 'SO- stop being evil' Jun 3 '15 at 23:11
0

My take. Similar to John1024's but as his is in one line, it's unreadable.
Tested on a Solaris 8 box.

/usr/xpg4/bin/awk \
    -v section_start='^----------------------------------------------------------------------  Cap in MB' \
    -v delete_marker='^---------------------------------------------------  Cap in MB' \
'
    $0 ~ section_start {
        for (i=1; i<=n; i++) 
            print line[i]
        n=0
        delete line
        print
        next    
    }
    {line[++n] = $0}
    $0 ~ delete_marker {
        n=1
        delete line
        line[1] = "Deleted up to this point"
    }
    END {for (i=1; i<=n; i++) print line[i]}
' foo.txt
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.