Em um script complexo que estou usando grep
para obter linhas correspondentes usando um arquivo de padrão
Por exemplo: Aqui está o arquivo contendo o texto
$ cat file.txt
abc$(SEQ)asdasd
wwww$(SEQ)asqqqqqq
efg hij$(SEQ)asdasdasd$(SEQ)zzzzzz
klmn$(SEQ)11111111
op$(SEQ)44444444
qrs$(SEQ)777
tuv$(SEQ)mmmmmmmmm
qrs$(SEQ)777444
asdsd777hdhfgjdfasd
wxyzfhdfghdfh
e aqui está o arquivo de padrão
$ cat pattren.txt
444
777
asd
Estou usando o seguinte grep
comando para obter as linhas correspondentes
Na linha de comando, consigo ver qual padrão é correspondido, mas não nos logs quando ele é registrado. Portanto, preciso de uma maneira de imprimir a linha correspondida e o padrão que foi correspondido. A saída deve ser algo como isto: Padrão impresso após TAB (ou qualquer formato reconhecível)
abc$(SEQ)asdasd <TAB> asd
efg hij$(SEQ)asdasdasd$(SEQ)zzzzzz <TAB> asd
op$(SEQ)44444444 <TAB> 444
qrs$(SEQ)777 <TAB> 444
qrs$(SEQ)777444 <TAB> 777444
asdsd777hdhfgjdfasd <TAB> asd777
Posso usar grep com , -o
mas não consigo combinar os dois (ou seja, com e sem -o
).
Não é necessário usar grep
, ficarei feliz em usar qualquer outro comando que possa fazer isso.
Uma
awk
ideia:Alternativamente, coloque o corpo do
awk
script em um arquivo e acesse viaawk -f ...
:NOTAS:
patterns.txt
não têm nenhum espaço em branco inicial/final, o que causariaindex()
falha na chamada(ptn in ptns)
não garante a ordem em que os padrões são processados, o que significa que não há garantia da ordem dos padrões quando impressos no final da linha; embora código adicional possa ser adicionado para atender a um requisito de ordem , o OP precisaria fornecer mais detalhes para incluir como lidar com padrões duplicados e/ou sobrepostos (por exemplo,a
eas
corresponderia na mesmaindex()
posição, então qual padrão seria considerado a correspondência real?)index()
só encontraremos a 1ª ocorrência de um padrão, e não fazemos nenhuma tentativa de correspondência além dessa primeira correspondência, essa abordagem apenas nos diz que há pelo menos uma correspondência; codificação adicional seria necessária para determinar o número de correspondências, mas também exigiria detalhes adicionais do OP sobre como processar padrões duplicados e/ou sobrepostos (por exemplo, quantas vezes4
e44
correspondem a44444444
?)Ambas as abordagens geram:
Como qualquer formato reconhecível é permitido, a solução mais simples é substituir as sequências ANSI emitidas pelo grep diretamente por qualquer separador que você quiser, como uma tabulação:
Também é possível capturar cada correspondência entre a sequência ANSI inicial e final, por exemplo, aqui eu envolvo cada correspondência dentro
[]
Para imprimir os padrões no final você pode usar algo assim
Se você quiser preservar a cor para uso posterior, você também pode fazer isso diretamente
Para fazer isso em Perl, use isto:
Saída:
O "one-liner" do Perl usa estes sinalizadores de linha de comando:
-e
: Diz ao Perl para procurar código em linha, em vez de em um arquivo.-n
: Faz um loop na entrada, uma linha de cada vez, atribuindo-a$_
por padrão.-l
: Remove o separador de linha de entrada ("\n"
por padrão no *NIX) antes de executar o código em linha e o anexa ao imprimir.O regex usa este modificador:
g
: Corresponde ao padrão repetidamente.A linha acima lê o conteúdo do
pattern.txt
arquivo em uma matriz@pats
e remove as quebras de linha (chomp
).$pat = join "|", @pats;
: Une os padrões em uma única sequência, delimitada pelo operador|
(= OR ).@matches = m{($pat)}g
: compara os padrões repetidamente (m{...}g
) com a linha atual lida defile.txt
. Todas as correspondências são armazenadas em uma matriz@matches
(que pode conter repetições do mesmo padrão, se ocorrer mais de uma vez).if ( @matches = ... )
:@matches
avaliaTRUE
se há pelo menos uma correspondência.@uniq = grep !$seen{$_}++, @matches;
: Torna as correspondências únicas e as armazena em@uniq
uma matriz.$uniq = join ",", @uniq;
: Une as correspondências únicas em uma vírgula e armazena o resultado em uma única sequência$uniq
.Veja também:
perldoc perlrun
: como executar o interpretador Perl: opções de linha de comandoperldoc perlre
: Expressões regulares Perl (regexes)perldoc perlrequick
: Início rápido de expressões regulares em Perl