Script BASH - Lendo saída e cortando por valor

Script BASH - Lendo saída e cortando por valor

Estou tentando criar um script BASH que executará um comando, filtrará a saída desse comando e, em seguida, lerá os resultados dessa saída para imprimir apenas as seções que atendem ao requisito especificado.

Por exemplo:

Consegui reduzir a saída do comando original para que a saída fique assim:

Profile: 1
PsA of Profile 1: 13
PsL of Profile 1: 15
Profile: 2
PsA of Profile 2: 0
PsL of Profile 2: 0

Estou tentando escrever um script BASH que leia cada seção de perfil individualmente e imprima apenas os números de perfil que possuem valores de PsA e PsL acima de 0.

Para maior clareza, a saída precisa ser apenas o valor do perfil, portanto, neste exemplo - 1, com 2 descartado.

Também precisa ser um script BASH devido ao trabalho que estou tentando fazer.

Eu sou realmente novo em tudo isso e estou totalmente preso. Por favor ajude!

** EDIT ** Para maior clareza, estou tentando trabalhar com o Volatility Framework. Estou analisando os perfis que podem ser obtidos e, atualmente, a saída exata é assim:

Profile suggestion (KDBGHeader): WinXPSP3x86
PsActiveProcessHead           : 0x8055a158 (31 processes)
PsLoadedModuleList            : 0x80553fc0 (122 modules)
Profile suggestion (KDBGHeader): WinXPSP2x86
PsActiveProcessHead           : 0x8055a158 (31 processes)
PsLoadedModuleList            : 0x80553fc0 (122 modules)

O que eu preciso é que o script verifique PsActiveProcessHead e PsLoadedModuleList (PsA e PsL) - especificamente, o número de processos e módulos encontrados - se AMBOS os mostrados entre colchetes estiverem acima de 0, imprima a sugestão de perfil. Pode haver uma sugestão de perfil, pode haver mais - preciso que o script gere qualquer perfil encontrado que tenha módulos e processos listados acima de 0.

Peço desculpas pela pergunta original pouco clara. Tentei simplificá-la e adaptar as respostas, mas ainda estou com dificuldades. Desculpe!

(Para ficar bem claro, o texto acima é apenas um exemplo do formato de saída, nem sempre ambos terão números acima de 0 e pode haver mais de 2 sugestões de perfil)

Responder1

Você pode usar sedcom um N;Desquema:

sed -n 'N;s/PsA\( of Profile \([0-9]*\): \)[^0].*\nPsL\1[^0].*/\2/p;D'

O Nanexa a próxima linha, então você sempre terá duas no espaço padrão. Então você simplesmente define um padrão com ambos os valores do mesmo perfil e um número que não começa com zero (portanto, valores com zeros à esquerda falharão!). Se houver uma correspondência, substitua o padrão pelo número do perfil referenciado e pimprima-o (enquanto a saída padrão está desabilitada por -nopção. Em seguida, comece novamente com D, reduzindo a linha anterior se houver duas.

Atualizar de acordo com a atualização da pergunta

Para o cenário do mundo real que você apresentou, sugiro uma abordagem diferente:

sed -n '/Profile suggestion/!d;h;n;/(0/d;n;//d;g;p' yourfile

Explicação:

  • /Profile suggestion/!dsignifica: elimine todas as linhas que não sejam sugestões de perfil. Pare o script aqui para continuar com a próxima linha.
  • hcopia a sugestão de perfil para o espaço de espera, para que possamos imprimi-la se necessário
  • ncontinua com a próxima linha. O atual não é impresso devido à -nopção do sedcomando
  • /(0/dexclui este ciclo se encontrarmos o padrão (0, porque isso significa que não há processos
  • n;//dexatamente como acima, para garantir que a segunda linha também tenha processos
  • Neste ponto do script sabemos que tivemos uma sugestão de prilfe com duas linhas a seguir, cada uma com um número diferente de zero de processos. gcopia o espaço de retenção de volta para o espaço padrão, para que possamos pimprimir a sugestão

Responder2

awk -F": " '
    $0~/^PsA/ && $2 > 0 
    {
        getline; 
        if($2 <= 0) next; 
        sub(/[^0-9]*/, "", $1); 
        print $1
     }' data

Supondo que PsAvenha primeiro PsLquando encontrarmos isso, pegue a próxima linha de texto ( getline) e verifique se o valor é maior que 0.

Se isso for bem-sucedido, explore o fato de que o registro PsAe PsLcontém, ele próprio, o nome do perfil. Pegue isso da linha e imprima.


Com base na sua edição:

awk -F": " '
    $0~/^Profile/ && h=$0 {next} 
    $1~/^PsA/ && $2~/\([^0]/ {
        getline; 
        if ($2~/\([^0]/) print h
    }' data

Se a linha atual começar com Profile, salve todo o cabeçalho e vá para a próxima linha.

Se o primeiro campo começar com PsAe dentro dos colchetes não for 0, pegue a próxima linha e faça a mesma verificação, se tiver sucesso, imprima o cabeçalho.

Responder3

Usando o awk:

NOTA: input.txté um arquivo de texto contendo sua amostra de entrada, para teste. Você pode simplesmente canalizar a saída do seu comando diretamente para este script awk.

$ awk -F' +|\\(' '/^Profile/ {p=$0};
                  /^PsA/ {a=$5};
                  /^PsL/ {l=$5};
                  a > 0 && l > 0 && p {print p; p=""; a=0; l=0}' input.txt 
Profile suggestion (KDBGHeader): WinXPSP3x86
Profile suggestion (KDBGHeader): WinXPSP2x86

input.txté um arquivo de texto contendo sua amostra de entrada, para teste. Você pode simplesmente canalizar a saída do seu comando diretamente para este script awk.

Isso diz awkpara usar um ou mais espaçosouum parêntese aberto como separador de campos (o que significa que o quinto campo, $5, conterá os processos relevantes ou a contagem de módulos).

O script awk lê o arquivo de entrada e para linhas que começam com "Profile", ele captura a linha inteira ( $0) na variável p.

Para linhas iniciadas por “PsA” ou “PsL”, captura a contagem em variáveis a​​ou lrespectivamente, a partir do quinto campo ( $5).

Finalmente, sempre que ambos ae lforem maiores que 0 e pnão estiverem vazios, ele imprime a linha do perfil capturada anteriormente pe redefine as variáveis a​​e lpara zero e ppara a string vazia.

Alternativamente, se você quiser apenas os nomes de perfis sugeridos (que também estão no quinto campo das linhas Perfil):

$ awk -F' +|\\(' '/^Profile/ {p=$5};
                  /^PsA/ {a=$5};
                  /^PsL/ {l=$5};
                  a > 0 && l > 0 && p {print p; p=""; a=0; l=0}' input.txt 
WinXPSP3x86
WinXPSP2x86

informação relacionada