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 sed
com um N;D
esquema:
sed -n 'N;s/PsA\( of Profile \([0-9]*\): \)[^0].*\nPsL\1[^0].*/\2/p;D'
O N
anexa 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 p
imprima-o (enquanto a saída padrão está desabilitada por -n
opçã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/!d
significa: elimine todas as linhas que não sejam sugestões de perfil. Pare o script aqui para continuar com a próxima linha.h
copia a sugestão de perfil para o espaço de espera, para que possamos imprimi-la se necessárion
continua com a próxima linha. O atual não é impresso devido à-n
opção dosed
comando/(0/d
exclui este ciclo se encontrarmos o padrão(0
, porque isso significa que não há processosn;//d
exatamente 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.
g
copia o espaço de retenção de volta para o espaço padrão, para que possamosp
imprimir a sugestão
Responder2
awk -F": " '
$0~/^PsA/ && $2 > 0
{
getline;
if($2 <= 0) next;
sub(/[^0-9]*/, "", $1);
print $1
}' data
Supondo que PsA
venha primeiro PsL
quando 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 PsA
e PsL
conté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 PsA
e 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 awk
para 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 l
respectivamente, a partir do quinto campo ( $5
).
Finalmente, sempre que ambos a
e l
forem maiores que 0 e p
não estiverem vazios, ele imprime a linha do perfil capturada anteriormente p
e redefine as variáveis a
e l
para zero e p
para 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