8

I have this store in a variable

   sCellEventTrap-03-28 TRAP-TYPE  -- CAC Code: 00
        ENTERPRISE compaq
        VARIABLES  { scellNameDateTime,
                     scellSWComponent,
                     scellECode,
                     scellCAC,
                     scellEIP}
        DESCRIPTION
             "Severity: Normal -- informational in nature. A physical disk drive has experienced an ID block inconsistency during a periodic drive check."
           --#TYPE      "StorageCell Event"
           --#SUMMARY   "SCellName-TimeDate %s : SWCID %d : ECode: %d : CAC %d : EIP %d."
           --#ARGUMENTS {0,1,2,3,4,}
           --#SEVERITY  INFORMATIONAL
           --#TIMEINDEX 136
           --#STATE     WARNING
        ::= 13600808

I am to cut everything till second occurrence of ". So that would give me:

 sCellEventTrap-03-28 TRAP-TYPE  -- CAC Code: 00
        ENTERPRISE compaq
        VARIABLES  { scellNameDateTime,
                     scellSWComponent,
                     scellECode,
                     scellCAC,
                     scellEIP}
        DESCRIPTION
             "Severity: Normal -- informational in nature. A physical disk drive has experienced an ID block inconsistency during a periodic drive check."

Another Example

    genericSanEvent TRAP-TYPE
        ENTERPRISE hpSanManager
        VARIABLES  { severityLevel, category, id,
                     msgString, contactName, contactEmail,
                     contactWorkPhone, contactHomePhone, 
                     contactPager, contactFax }
        DESCRIPTION
                        "A generic SAN event has occurred.  The variables are:
                            severityLevel - the event severity level;
                            category - Category of the event being reported;
                            code - ID of the event in the given category;
                            msgString - the message string describing
                                the event;
                            contactName - the name of the individual
                                to be notified of the event;
                            contactEmail - the e-mail address of the
                                individual referred to in contactName;
                            contactWorkPhone - the work phone number
                                of the individual referred to in 
                                contactName;
                            contactHomePhone - the home phone number
                                of the individual referred to in 
                                contactName;
                            contactPager - the pager number of the 
                                individual referred to in contactName;
                            contactFax - the FAX number of the individual
                                 referred to in contactName"
     -- The following are attributes used by xnmloadmib for improved formatting
     --#TYPE "OV SAM SAN Event"
     --#SUMMARY "OV SAM SAN Event, Category/Id: %d/%d, Msg: %d  Severity: %d  Contact: %d"
     --#ARGUMENTS {1,2,3,0,4}
     --#SEVERITY CRITICAL
     --#GENERIC 6
     --#CATEGORY "Application Alert Events"
     --#SOURCE_ID "T"
        ::= 1

Output for this example should be :

    genericSanEvent TRAP-TYPE
        ENTERPRISE hpSanManager
        VARIABLES  { severityLevel, category, id,
                     msgString, contactName, contactEmail,
                     contactWorkPhone, contactHomePhone, 
                     contactPager, contactFax }
        DESCRIPTION
                        "A generic SAN event has occurred.  The variables are:
                            severityLevel - the event severity level;
                            category - Category of the event being reported;
                            code - ID of the event in the given category;
                            msgString - the message string describing
                                the event;
                            contactName - the name of the individual
                                to be notified of the event;
                            contactEmail - the e-mail address of the
                                individual referred to in contactName;
                            contactWorkPhone - the work phone number
                                of the individual referred to in 
                                contactName;
                            contactHomePhone - the home phone number
                                of the individual referred to in 
                                contactName;
                            contactPager - the pager number of the 
                                individual referred to in contactName;
                            contactFax - the FAX number of the individual
                                 referred to in contactName"

2
  • @John1024 I was trying this sed 's/"[^"]*$//' but what it does is it only deletes the " and nothing after that. So the whole thing remains only a " is deleted.
    – SamFlynn
    Jun 29, 2015 at 3:17
  • @John1024 also tried this awk -F ""\" '{print $1 (NF>1? FS $2 : "")}' temp1 but the same thing as above happens.
    – SamFlynn
    Jun 29, 2015 at 3:48

5 Answers 5

10

Using awk:

awk -v RS='"' -v ORS='"' 'NR==1{print} NR==2{print; printf"\n";exit}' file

This sets the record separator to ". So, we want to print the first two records and then we are done. In more detail:

  • -v RS='"'

    This sets the input record separator to a double quote.

  • -v ORS='"'

    This sets the out record separator to a double quote.

  • NR==1{print}

    This tells awk to print the first line.

  • NR==2{print; printf"\n";exit}

    This tells awk to print the second line, then print a newline character, and then exit.

Using sed

sed -r 'H;1h;$!d;x; s/(([^"]*"){2}).*/\1/' file

This reads the whole file in at once. So, if the file is huge, don't use this approach. It works as follows:

  • H;1h;$!d;x

    This is a useful sed idiom: it reads the whole file in at once.

  • s/(([^"]*"){2}).*/\1/

    This looks for the second " and then deletes all text which follows the second quote.

    The regex (([^"]*"){2}) captures all text up to and including the second double quote and saves it in group 1. The regex .* captures everything that follows to the end of the file. The replacement text is group 1, \1.

2
  • Here I was trying to write a sed line, but only came up with sed -e '0,/"/! {$!N;d;}' temp1 which worked on his first one, but failed miserably on the second one. Good job on your answer. It definitely covers both! +1
    – Terrance
    Jun 29, 2015 at 5:31
  • Suggestion: try NR < 3. That should shorten the code. Jun 30, 2015 at 3:17
3

Using Perl:

< infile perl -0777 -pe 's/((.*?"){2}).*/$1/s' > outfile
  • -0777: slurps the whole file at once instead of one line at the time
  • -p: places a while (<>) {[...]} loop around the script and prints the processed file
  • -e: reads the script from the arguments

Perl command breakdown:

  • s: asserts to perform a substitution
  • /: starts the pattern
  • ((.*?"){2}): matches and groups any number of any character zero or more times lazily within the current file (i.e. it matches the least times as possible, stopping when the following pattern starts to match) before a " character, twice
  • .*: matches any number of any character zero or more times greedily within the current file (i.e. it matches the most times as possible)
  • /: stops the pattern / starts the replacement string
  • $1: replaces with the first captured group
  • /: stops the replacement string / starts the modifiers
  • s: treats the whole file as a single line, allowing . to match also newlines
3

Though many programs dont like very long lines as input, when your data is not huge you can often simplify multi-line matching by first manipulating the data to put it all on one line, doing the match, then restoring the newlines.

For example, use tr to replace newline \n by some character not in your data (I used carriage-return `\r'), use sed to change this single line, then tr the character back:

tr '\n' '\r' < file |
sed 's/\("[^"]*"\).*/\1/' |
( tr '\r' '\n';  echo ) # add a final newline

Otherwise, though you state you want sed/awk/grep, languages like perl and python use similar regular expressions as these and are good for manipulating multi-line strings. Eg perl:

perl -e '$_ = join("",<>); s/(".*?").*/$1/s; print "$_\n"; ' file
3

Here is a little python script:

#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
    print '"'.join(f.read().split('"')[:2]) + '"'
  • f.read().split('"') will read the whole file as a string and then split it on " to get all the " separated portions

  • As we are interested in only the first two " separated portions, '"'.join(f.read().split('"')[:2]) will join the first two with "

  • Then at last we have added a " to get the desired format.

2

Here's a shorter awk version: awk '/TRAP-TYPE/,/[[:alpha:]]*"$/ '

$ awk '/TRAP-TYPE/,/[[:alpha:]]*"$/ ' testfile.txt                             
   sCellEventTrap-03-28 TRAP-TYPE  -- CAC Code: 00
        ENTERPRISE compaq
        VARIABLES  { scellNameDateTime,
                     scellSWComponent,
                     scellECode,
                     scellCAC,
                     scellEIP}
        DESCRIPTION
             "Severity: Normal -- informational in nature. A physical disk drive has experienced an ID block inconsistency during a periodic drive check."


$ awk '/TRAP-TYPE/,/[[:alpha:]]*"$/ ' testfile2.txt                                                 
    genericSanEvent TRAP-TYPE
        ENTERPRISE hpSanManager
        VARIABLES  { severityLevel, category, id,
                     msgString, contactName, contactEmail,
                     contactWorkPhone, contactHomePhone, 
                     contactPager, contactFax }
        DESCRIPTION
                        "A generic SAN event has occurred.  The variables are:
                            severityLevel - the event severity level;
                            category - Category of the event being reported;
                            code - ID of the event in the given category;
                            msgString - the message string describing
                                the event;
                            contactName - the name of the individual
                                to be notified of the event;
                            contactEmail - the e-mail address of the
                                individual referred to in contactName;
                            contactWorkPhone - the work phone number
                                of the individual referred to in 
                                contactName;
                            contactHomePhone - the home phone number
                                of the individual referred to in 
                                contactName;
                            contactPager - the pager number of the 
                                individual referred to in contactName;
                            contactFax - the FAX number of the individual
                                 referred to in contactName"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .