Como eu apago tudo após a segunda ocorrência de aspas usando a linha de comando?

6

Eu tenho essa loja em uma variável

   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

Eu devo cortar tudo até a segunda ocorrência de " . Então isso me daria:

 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."

Outro exemplo

    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

A saída para este exemplo deve ser:

    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"

    
por SamFlynn 29.06.2015 / 05:02

5 respostas

9

Usando o awk:

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

Isso define o separador de registro como " . Então, queremos imprimir os dois primeiros registros e depois terminamos. Mais detalhadamente:

  • -v RS='"'

    Isso define o separador de registro de entrada como uma aspa dupla.

  • -v ORS='"'

    Isso define o separador de registro out como uma aspa dupla.

  • NR==1{print}

    Isto diz ao awk para imprimir a primeira linha.

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

    Isso diz ao awk para imprimir a segunda linha, depois imprimir um caractere de nova linha e, em seguida, sair.

Usando sed

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

Isto lê todo o arquivo de uma só vez. Então, se o arquivo é enorme, não use essa abordagem. Funciona da seguinte forma:

  • H;1h;$!d;x

    Este é um idioma útil sed: lê o arquivo inteiro de uma vez.

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

    Isso procura o segundo " e, em seguida, exclui todo o texto que segue a segunda citação.

    O regex (([^"]*"){2}) captura todo o texto até e inclui a segunda aspa dupla e o salva no grupo 1. O regex .* captura tudo o que segue até o final do arquivo. O texto de substituição é o grupo 1, .

por John1024 29.06.2015 / 07:29
3

Usando o Perl:

< infile perl -0777 -pe 's/((.*?"){2}).*//s' > outfile
  • -0777 : faz o slurps do arquivo inteiro de uma só vez, em vez de uma linha no momento
  • -p : coloca um loop while (<>) {[...]} ao redor do script e imprime o arquivo processado
  • -e : lê o script dos argumentos

Divisão do comando Perl:

  • s : afirma para executar uma substituição
  • / : inicia o padrão
  • ((.*?"){2}) : combina e agrupa qualquer número de qualquer caractere zero ou mais vezes preguiçosamente no arquivo atual (isto é, corresponde ao menor número de vezes possível, parando quando o padrão a seguir começa a corresponder) antes de um caractere " , duas vezes
  • .* : corresponde a qualquer número de qualquer caractere zero ou mais vezes avidamente no arquivo atual (ou seja, corresponde ao máximo de vezes possível)
  • / : interrompe o padrão / inicia a sequência de substituição
  • : substitui pelo primeiro grupo capturado
  • / : interrompe a string de substituição / inicia os modificadores
  • s : trata o arquivo inteiro como uma única linha, permitindo que . corresponda também a novas linhas
por kos 29.06.2015 / 12:34
3

Embora muitos programas não gostem de linhas muito longas como entrada, quando seus dados são não é enorme, muitas vezes você pode simplificar a correspondência de várias linhas manipulando primeiro os dados para colocar tudo em uma linha, fazendo a partida, depois restaurando as novas linhas.

Por exemplo, use tr para substituir a nova linha \n por algum caractere que não esteja em seus dados (usei carriage-return '\ r'), use sed para alterar essa linha única, então tr o personagem de volta:

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

Caso contrário, embora você afirme que deseja sed / awk / grep, idiomas como perl e python usar expressões regulares semelhantes como estas e são boas para manipulando seqüências de várias linhas. Por exemplo, perl:

perl -e '$_ = join("",<>); s/(".*?").*//s; print "$_\n"; ' file
    
por meuh 29.06.2015 / 11:59
3

Aqui está um pequeno script de python :

#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
    print '"'.join(f.read().split('"')[:2]) + '"'
  • f.read().split('"') lerá o arquivo inteiro como uma string e depois dividirá em " para obter todas as " porções separadas

  • Como estamos interessados apenas nas duas primeiras partes separadas " , '"'.join(f.read().split('"')[:2]) unirá as duas primeiras com "

  • Então, finalmente, adicionamos um " para obter o formato desejado.

por heemayl 30.06.2015 / 01:02
2

Aqui está uma versão awk mais curta: 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"
    
por Sergiy Kolodyazhnyy 29.06.2015 / 13:15