Condição que corresponde a todas as ocorrências de uma palavra em um anúncio de arquivo faz algo

2

Eu devo fazer algo assim

for (( every occurrence of the word TRAP-TYPE in a file )) 
do 
desc="$(< inputfile awk '/DESCRIPTION/ {getline; gsub(/^\s*"/, ""); gsub(/"\s*$/, ""); print}')"

casenum="$(< inputfile awk '/::=/ {gsub(/^\s*::=\s*/, ""); gsub(/\s*$/, ""); print}')"

echo $desc $numvar $casenum 
done

Ele procurará todas as ocorrências de TRAP-TYPE . Qualquer idioma serve!

ENTRADA

sCSISmart20 TRAP-TYPE
ENTERPRISE cyclone
DESCRIPTION
"Aspi: unable to read the file server hard disk might have problems"
--#TYPE "Aspi: unable to read the database file"
--#SUMMARY "ASPI: unable to read the file, server hard disk may have problems"
--#ARGUMENTS {}
--#SEVERITY WARNING
--#TIMEINDEX 100
--#STATE OPERATIONAL
--#HELP "scsismrt.hlp"
--#HELPTAG 124
::= 124

sCSISmart21 TRAP-TYPE
ENTERPRISE cyclone
DESCRIPTION
"Aspi: database is corrupted"
--#TYPE "Aspi: database is corrupted"
--#SUMMARY "ASPI: database file is corrupted"
--#ARGUMENTS {}
--#SEVERITY WARNING
--#TIMEINDEX 100
--#STATE OPERATIONAL
--#HELP "scsismrt.hlp"
--#HELPTAG 125 ::= 125

sCSISmart12 TRAP-TYPE
ENTERPRISE cyclone
VARIABLES {cycHostAdapterNumber, cycScsiTargetID, cycLun, cycVendor, cycProduct, cycSenseInfo}
DESCRIPTION
"The HostAdapter# %d, TargetID %d, Lun# %d has Predictive Failure Condition on vendor %s product %s with sense info MSB(sense code), next 8 bits (sense code Qual) next 8 bits (Add sense code Qual) LSB (0000) %d"
--#TYPE "Device has SMART/Predicictive failure event"
--#SUMMARY "The HostAdapter# %d , TargetID %d, Lun# %d has Predictive Failure Condition on vendor %s product %s with senseinfo %d"
--#ARGUMENTS {0,1,2,3,4,5}
--#SEVERITY INFORMATIONAL
--#TIMEINDEX 100
--#STATE OPERATIONAL
--#HELP "scsismrt.hlp"
--#HELPTAG 116
::= 116

OUTPUT

Aspi: unable to read the file server hard disk might have problems             
124
Aspi: database is corrupted            
125 

Desculpe pelo mal-entendido. Eu sou atormentado por conectividade de internet ruim.

    
por SamFlynn 15.06.2015 / 14:33

5 respostas

2

TRABALHO EM PROGRESSO

A extração de dados é fácil:

awk '{ if($0~/DESCRIPTION/){getline;print $0}; if($0~/::=/) print $2}' testfile

A execução desse arquivo de teste que contém o texto de entrada que você publicou fornece essa saída:

$ awk '{if($0~/DESCRIPTION/){getline;print $0}; if($0~/::=/) print $2}' testfile                      
    "Aspi: unable to read the file server hard disk might have problems"
124
    "Aspi: database is corrupted"
125

Se vamos ter vários arquivos lá, o código pode ser editado da seguinte forma:

$ awk 'FNR==1{print FILENAME"\n========"} { if($0~/DESCRIPTION/){getline;print $0}; if($0~/::=/) print $2}' *.test                  
file1.test
========
    "Aspi: unable to read the file server hard disk might have problems"
124
    "Aspi: database is corrupted"
125
file2.test
========
    "Aspi: second file"
134
    "Aspi: i love awk"
135

Isso é apenas para extrair dados. Continuarei editando esta resposta para incluir como você pode atribuir dados extraídos a variáveis.

Uma abordagem é usar a função system do awk, que permitirá executar comandos shell com variáveis passadas pelo awk. Nesta função, o comando deve estar entre aspas duplas e as variáveis internas do awk fora das aspas. Por exemplo, algo assim:

awk '{ if($0~/DESCRIPTION/){getline;printf $0"|"}; if($0~/::=/) printf $2"\n"}' *.test | awk -F'|' '{ STRING=$1;NUM=$2; system("echo this is the NUMBER "NUM" and this is the TEXT  "STRING)   }'

Saída:

this is the NUMBER 124 and this is the TEXT Aspi: unable to read the file server hard disk might have problems
this is the NUMBER 125 and this is the TEXT Aspi: database is corrupted
this is the NUMBER 134 and this is the TEXT Aspi: second file
this is the NUMBER 135 and this is the TEXT Aspi: i love awk

Uma forma possível de atribuir saída a variáveis seria com dois arrays parralel.

$   IFS="|"; STRING_ARRAY=($(awk ' /DESCRIPTION/ {getline;printf "%s|",$0}; /::=/ { printf $2"\n" }' trapfile.txt | awk -F'|' '{printf "%s|",$1}'))

$ echo ${STRING_ARRAY[*]}
    "Aspi: unable to read the file server hard disk might have problems"     "Aspi: database is corrupted"     "Aspi: second file"     "Aspi: i love awk"

Lá, usei o separador de campo interno IFS | e criei a matriz de cadeias como processada pelos dois comandos awk. Agora que STRING_ARRAY pode ser usado em um loop for. Para gerar os números apropriados para uma matriz:

$ IFS="|"; NUMS_ARRAY=($(awk ' /DESCRIPTION/ {getline;printf "%s|",$0}; /::=/ { printf $2"\n" }' trapfile.txt | awk -F'|' '{printf "%s|",$2}'))

$ echo ${NUMS_ARRAY[*]}
124 125 134 135

Agora temos dois arrays parrallel, com cada string e número de correspondência de índice de cada ocorrência em qualquer arquivo

Note que o código no primeiro pipe é o mesmo, então podemos simplificar isso, fazendo um script awk:

#!/usr/bin/awk -f
# Author: SergKolo
# Date: June 16,2015
# Written for: http://askubuntu.com/q/636705/295286
# Awk script to extract text
# between two specific strings
# in a file


{

          if($0~/DESCRIPTION/)
          {
            getline;printf "%s|",$0
          }; 

          if($0~/::=/) { printf $2"\n" }

}

Salve esse script em um arquivo com algum nome, chmod +x scriptname.awk . Agora esses longos comandos simplificam como:

$ IFS="|"; LINES_ARRAY=($(trap-script.awk trapfile.txt | awk -F'|' '{printf "%s|",$1}' ))

e

$ IFS="|"; NUMBERS_ARRAY=($(trap-script.awk trapfile.txt | awk -F'|' '{printf "%s|",$2}' ))

Observação: porque, fora da nossa conversa nos comentários, ficou claro que alguns dos seus arquivos contêm linhas com %d e %s format, caracteres, e eu incluí printf "%s|",$0 gosta do código por um motivo. Quando a função printf expande uma linha $ 0 e vê esses caracteres de formato, assume que deve haver entrada para eles, em vez de tratá-los como uma cadeia longa. printf "%s|",$0 permite tratar esses caracteres% d como texto, não como algo que precisa de entrada.

    
por Sergiy Kolodyazhnyy 15.06.2015 / 16:56
2

Outra solução para o awk:

$ gawk -F '\n *' -v RS="::=[^\n]*\n*" '{gsub(/[^0-9]/,"", RT); printf "%s\n%s\n", $4, RT}' foo
"Aspi: unable to read the file server hard disk might have problems"                           
124
"Aspi: database is corrupted"                                                  
125

O texto naturalmente se divide em registros, mas o separador de registros não é muito simples. Pode ser duas novas linhas consecutivas. Decidi usar o último campo no registro ( ::= ... ), seguido por arbitrariamente muitas novas linhas, como separador de registro.

Em seguida, para dividir em campos, usei uma nova linha seguida de muitos espaços arbitrariamente. Depois disso, é só imprimir o quarto campo e extrair os números do texto do separador de registro ( RT ). Como esta solução usa RT , é apenas o GNU awk.

    
por muru 15.06.2015 / 19:48
1

No seu cenário, as ocorrências de uma palavra podem ser encontradas com awk, grep e sed; mas você teria que encaixar aqueles em um script bash com algumas declarações de caso e uma iteração. Pode ser feito. Escrever um programa Perl, Python, Java ou C ++ parece ser uma maneira melhor de fazê-lo.

Eu só escrevi isso para você. Este é um programa em c ++. Copie e cole o programa abaixo no gedit. Salve como findword.cpp. NOTA: você precisa construir-essencial para compilar.

:~$ sudo apt-get install build-essential -y

:~$ g++ -o findword findword.cpp

O programa:

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <locale>

using namespace std;

int main()
{
    string wordhold = "";
    int index;
    string line;
    string trptype = "TRAP-TYPE";

    ifstream infile;
    infile.open("Yourfile.txt"); // change Yourfile.txt to the name of the file

    while ( getline(infile, line) ) {

        index = line.find('\n');
        string holdword = line.substr(0,index);
        wordhold = holdword;

        if ( wordhold.compare(wordhold.size(),9,trptype) == 0 ) {

            system("Execute the command you want inside the quotes");
            wordhold = "";

        }
        else {

            wordhold = "";

        }

    }
    infile.close();

    cout << "The file is closed\nDone" << endl;

    return 0;   
}

Você pode executar vários comandos duplicando a função do sistema que está na declaração de condição (if).

Para executar o programa, digite o diretório em que você compilou e execute-o a partir da linha de comando.

:~$ ./findword

Boa sorte.

    
por oOpSgEo 15.06.2015 / 15:12
1

Usando awk :

< inputfile awk '/DESCRIPTION/ {getline; sub(/^ *"/,""); sub(/"$/,""); print}; /::=/ {sub(/::= */,""); print}'

Versão expandida:

< inputfile awk '
    /DESCRIPTION/ {
        getline;
        sub(/^ *"/,"");
        sub(/"$/,"");
        print
    };
    /::=/ {
        sub(/^::= */,"");
        print
    }
'
  • /DESCRIPTION/ : seleciona apenas os registros que contêm a string DESCRIPTION
  • getline : pula o primeiro registro
  • sub(/^ *"/,"") : substitua uma string composta por qualquer número de espaços seguido por um caractere " , no início da linha, com uma string vazia
  • sub(/"$/,"") : substitua um caractere " , no final da linha, por uma string vazia
  • print : imprime o registro
  • /::=/ : seleciona apenas os registros que contêm a string ::=
  • sub(/^::= */,"") : substitua uma string composta por ::= seguida por qualquer número de espaços, no início da linha, com uma string vazia
  • print : imprime o registro
por kos 15.06.2015 / 16:45
1

Minha awk versão:

awk '/TRAP-TYPE/ {traptype=1}; traptype && /DESCRIPTION/ {getline; gsub(/^ +/, "", $0); gsub(/^\"/, "", $0); gsub(/\"\s+$/, "", $0); print}; traptype && /::=/ {print $2}' testfile

ou mais específico

awk '/sCSISmart.*TRAP-TYPE/ {traptype=1}; traptype && /DESCRIPTION/ {getline; gsub(/^ +/, "", $0); gsub(/^\"/, "", $0); gsub(/\"\s+$/, "", $0); print}; traptype && /::=/ {print $2}' testfile

Entrada

testfile

sCSISmart20 TRAP-TYPE                                  
    ENTERPRISE  cyclone                                                  
    DESCRIPTION                                          
    "Aspi: unable to read the file server hard disk might have problems"                           
    --#TYPE "Aspi: unable to read the database file"                                 
    --#SUMMARY "ASPI: unable to read the file, server hard disk may have                                                              problems"                                     
    --#ARGUMENTS {}                                 
    --#SEVERITY WARNING                                         
    --#TIMEINDEX 100                                                    
    --#STATE OPERATIONAL                                          
    --#HELP "scsismrt.hlp"                                                      
    --#HELPTAG 124                         
::=  124                                                                                            

sCSISmart21 TRAP-TYPE                                     
    ENTERPRISE  cyclone                                                
    DESCRIPTION                                                      
    "Aspi: database is corrupted"                                                  
    --#TYPE "Aspi: database is corrupted"                                          
    --#SUMMARY "ASPI: database file is corrupted"                                              
    --#ARGUMENTS {}                                                             
    --#SEVERITY WARNING                   
    --#TIMEINDEX 100                           
    --#STATE OPERATIONAL                              
    --#HELP "scsismrt.hlp"                        
    --#HELPTAG 125
::=  125

Saída

Aspi: unable to read the file server hard disk might have problems
124
Aspi: database is corrupted
125

Saídas separadas

awk '/TRAP-TYPE/ {traptype=1}; traptype && /DESCRIPTION/ {getline; gsub(/^ +/, "", $0); gsub(/^\"/, "", $0); gsub(/\"\s+$/, "", $0); print;}' testfile

Aspi: unable to read the file server hard disk might have problems
Aspi: database is corrupted

awk '/sCSISmart.*TRAP-TYPE/ {traptype=1}; traptype && /::=/ {print $2}' testfile

124
125
    
por A.B. 15.06.2015 / 20:16