Question

I have a scalar variable that contains some information inside of a file. My goal is to strip that variable (or file) of any multi-line entry containing the words "Administratively down."

The format is similar to this:

Ethernet2/3 is up
... see middle ...
a blank line
VlanXXX is administratively down, line protocol is down
... a bunch of text indented by two spaces on multiple lines ...
a blank line
Ethernet2/5 is up
... same format as previously ...

I was thinking that if I could match "administratively down" and a leading newline (for the blank line), I would be able to apply some logic to the variable to also remove the lines between those lines.

I'm using Perl at the moment, but if anyone can give me an ios way of doing this, that would also work.

Was it helpful?

Solution

Use Perl's Paragraph Mode

Perl has a rarely-used syntax for using blank lines as record separators: the -00 flags; see Command Switches in perl(1) for details.

Example

For example, given a corpus of:

Ethernet2/3 is up
... see middle ...

VlanXXX is administratively down, line protocol is down
... a bunch of text indented by two spaces on multiple lines ...

Ethernet2/5 is up

You can use extract all pargagraphs except the ones you don't want with the following one-liner:

$ perl -00ne 'print unless /administratively down/' /tmp/corpus

Sample Output

When tested against your corpus, the one-liner yields:

Ethernet2/3 is up
... see middle ...

Ethernet2/5 is up

OTHER TIPS

So, you want to delete from the beginning of a line containing "administratively down" to and including the next blank line (two consecutive newlines)?

$log =~ s/[^\n]+administratively down.+?\n\n//s;

s/ = regex substitution

[^\n]+ = any number of characters, not including newlines, followed by

administratively down = the literal text, followed by

.+? = any amount of text, including newlines, matched non-greedily, followed by

\n\n = two newlines

// = replace with nothing (i.e. delete)

s = single line mode, allows . to match newlines (it usually doesn't)

You can use this pattern:

(?<=\n\n|^)(?>[^a\n]++|\n(?!\n)|a(?!dministratively down\b))*+administratively down(?>[^\n]++|\n(?!\n))*+

details:

(?<=\n\n|^)  # preceded by a newline or the begining of the string
# all that is not "administratively down" or a blank line, details:
(?>                               # open an atomic group
    [^a\n]++                      # all that is not a "a" or a newline
  |                               # OR
    \n(?!\n)                      # a newline not followed by a newline
  |                               # OR
    a(?!dministratively down\b)   # "a" not followed by "dministratively down"
)*+                               # repeat the atomic group zero or more times
administratively down             # "administratively down" itself
# the end of the paragraph
(?>                          # open an atomic group          
    [^\n]++                  # all that is not a newline
  |                          # OR
    \n(?!\n)                 # a newline not followed by a newline
)*+                          # repeat the atomic group zero or more times
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top