Eu tenho dois arquivos file1
e file2
.
O conteúdo da amostra file1
é:
A B
C D
E F
G H
e o conteúdo de file2
é como:
A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H
Quero pesquisar apenas todo o bloco de file1
conteúdo file2
. Isso significa que a saída deve conter apenas estas linhas:
A B
C D
E F
G H
observe que: - somente as linhas que estão se unindo devem fazer parte da saída.
shell-script
text-processing
awk
sed
sachin
fonte
fonte
file1
e nada mais, basta usarcat file1
.Respostas:
grep
é bastante estúpido quando se trata de padrões de múltiplas linhas, mas a conversão de todos os caracteres\n
de nova linha do padrão e do texto para pesquisar em caracteres NUL\0
antes de compará-los corrige isso. Também é necessário traduzir\0
a saída de volta para\n
.Aqui está o seu comando, supondo que
file1
contenha o padrão em que você deseja pesquisarfile2
:Exemplo de saída para os arquivos fornecidos:
Explicação:
<(tr '\n' '\0' < file1)
cria um objeto FIFO / pipe nomeado / semelhante a arquivo temporário igual afile1
, mas com todos os caracteres de nova linha traduzidos para caracteres NUL.<(tr '\n' '\0' < file2)
faz o mesmo, mas parafile2
.grep -f PATTERN_FILE INPUT_FILE
pesquisa os padrões a partirPATTERN_FILE
deINPUT_FILE
.-a
sinalizador degrep
habilita a correspondência em arquivos binários. Isso é necessário porque, caso contrário, pularia arquivos que contenham caracteres não imprimíveis, como\0
.-o
bandeira degrep
faz com que imprima apenas a sequência correspondente, não a linha inteira em que foi encontrada.| tr '\0' '\n'
converte todos os caracteres NUL da saída do comando no lado esquerdo para caracteres de nova linha.fonte
O seguinte é desajeitado, mas funciona com o GNU
awk
:fonte
Apenas por diversão em pura festa
fonte
Aqui está um pouco mais elegante
grep
+perl
:No entanto, há uma grande captura. Se houver uma nova linha à direita no
file1
, o padrão não será correta, ou seja:A B\nC D\nE F\nG H\n\n
.(Agradecimentos especiais @terdon por fornecer a parte perl)
Como costas observou, um pode ser usado
perl -0pe 's/\n(\n+$)?/\\n/g'
no lugar do outroperl
comando para evitar a nova linha à direita nofile1.txt
fonte
perl -0pe 's/\n(\n+$)?/\\n/g'
. Sem-0
og
regex, o modificador é extra.Não tenho muita certeza do que você deseja que a saída seja, mas é fácil fazer com idiomas que não são exclusivamente orientados a linhas (especialmente se os dois arquivos puderem ser lidos na memória). Aqui está um script python que informa quantas correspondências existem.
Deseja imprimir
file1
quantas vezes corresponder? Substitua a última linha por esta:Você pode agrupar tudo em uma chamada ou alias da linha de comando, se realmente quiser:
fonte
o resultado será todos os arquivos com correspondência exata de texto
fonte
Aqui está outra abordagem usando python (testado com
python3 3.5.2
, sem queixas depylint3 1.5.6
):O tratamento de argumentos de linha de comando via
sys.argv
é reconhecidamente simplista. Você poderia fazer muitas outras coisas com o valor de retorno dosfinder
doismemoryview
objetos pelos quais passa, além de passá-lo paratuple
. CadaSRE_Match
item gerado pelo iterador retornado porfinder
possui vários métodos, cuja amostra é resumida naprint
saída (span
por exemplo, informa o intervalo de bytes de cada correspondência).fonte