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.

3 Answers 3

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
10
  • syntax error, bailing out near line 1 Jun 3, 2015 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, 2015 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 Jun 3, 2015 at 22:45
  • @ayrton_senna Thanks. I also see here a report that nawk works better than awk on solaris.
    – John1024
    Jun 3, 2015 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, 2015 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
4
  • @Giles can you provide the command in a single line, im getting syntax error and bailing out near line 2 error Jun 3, 2015 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? Jun 3, 2015 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 Jun 3, 2015 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. Jun 3, 2015 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

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.