Como imprimir todas as linhas depois de uma partida até o final do arquivo?

37

O arquivo de entrada1 é:

dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

Eu dou a correspondência do padrão em other file (como dog 123 4335 do arquivo2).

Eu coincidir com o padrão da linha é dog 123 4335 e após a impressão todas as linhas sem linha de correspondência minha saída é:

cat 13123 23424
deer 2131 213132
bear 2313 21313

Se usar somente sem endereço da linha use apenas o padrão, por exemplo 1s como combinar e imprimir as linhas?

    
por loganaayahee 23.11.2012 / 08:17

11 respostas

24

Se você tiver um arquivo razoavelmente curto, grep sozinho poderá funcionar:

grep -A5000 -m1 -e 'dog 123 4335' animals.txt

5000 é apenas o meu palpite em "razoavelmente curto", pois grep encontra a primeira correspondência e gera a saída junto com as próximas 5.000 linhas (o arquivo não precisa ter tantas). Se você não quiser a correspondência em si, precisará cortá-la, por exemplo,

grep -A5000 -m1 -e 'dog 123 4335' animals.txt | tail -n+2

Se você não quer o primeiro, mas a última correspondência como delimitador, você pode usar isto:
tac animals.txt | sed -e '/dog 123 4335/q' | tac

Esta linha lê animals.txt na ordem inversa das linhas e gera até e inclui a linha com dog 123 4335 e depois reverte novamente para restaurar a ordem correta.

Novamente, se você não precisar da correspondência no resultado, anexe a parte final. (Você também pode complicar a expressão sed para descartar seu buffer antes de sair.)

    
por 02.07.2014 / 10:40
23

Supondo que você queira combinar toda a linha com seu padrão, com o GNU sed , isso funciona:

sed -n '/^dog 123 4335$/ { :a; n; p; ba; }' infile

Equivalente padrão:

sed -ne '/^dog 123 4335$/{:a' -e 'n;p;ba' -e '}' infile

Com a seguinte entrada ( infile ):

cat 13123 23424 
deer 2131 213132
bear 2313 21313
dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

A saída é:

cat 13123 23424 
deer 2131 213132
bear 2313 21313

Explicação:

  • /^dog 123 4335$/ procura o padrão desejado.
  • :a; n; p; ba; é um loop que busca uma nova linha da entrada ( n ), imprime ( p ) e ramifica de volta para rotular um :a; ...; ba; .

Atualizar

Aqui está uma resposta que se aproxima de suas necessidades, ou seja, padrão no arquivo2, grepping do arquivo1:

tail -n +$(( 1 + $(grep -m1 -n -f file2 file1 | cut -d: -f1) )) file1

O grep e cut embutidos localizam a primeira linha contendo um padrão do arquivo2, esse número de linha mais um é passado para o final, o mais um está lá para pular a linha com o padrão.

Se você quiser começar do último jogo em vez do primeiro, seria:

tail -n +$(( 1 + $(grep -n -f file2 file1 | tail -n1 | cut -d: -f1) )) file1

Note que nem todas as versões do tail suportam a notação de mais.

    
por 23.11.2012 / 08:36
18

Na prática, provavelmente usaria Resposta da Aet3miirah na maior parte do tempo e a resposta do alexey é maravilhosa quando se quer navegar pelas linhas (também, também funciona com less ). OTOH, eu realmente gosto de outra abordagem (que é uma espécie de invertida Resposta de Gilles :

sed -n '/dog 123 4335/,$p'

Quando chamado com o sinal -n , sed não imprime por padrão as linhas que ele processa mais. Em seguida, usamos um formulário de dois endereços que diz para aplicar um comando da linha correspondente /dog 123 4335/ até o final do arquivo (representado por $ ). O comando em questão é p , que imprime a linha atual. Então, isso significa "imprimir todas as linhas desde a correspondência /dog 123 4335/ até o final".

    
por 26.05.2015 / 15:49
14

$ more +/"dog 123 4335" file1

    
por 30.05.2013 / 15:27
13
sed -e '1,/dog 123 4335/d' file1

Se você precisar ler o padrão de um arquivo, substitua-o pelo comando sed. Se o arquivo contiver um padrão sed:

sed -e "1,/$(cat file2)/d" file1

Se o arquivo contiver uma string literal para procurar, cite todos os caracteres especiais. Presumo que o arquivo contenha uma única linha.

sed -e "1,/$(sed 's/[][\\/^$.*]/\&/g' file2)/d" file1

Se você quiser que a correspondência seja a linha inteira, não apenas uma subseqüência, envolva o padrão em ^…$ .

sed -e "1,/^$(sed 's/[][\\/^$.*]/\&/g' file2)\$/d" file1
    
por 24.11.2012 / 00:55
10

com awk :

awk 'BEGIN {getline pattern < "other file"}
   NR == 1, $0 ~ pattern {next}; {print}' < "input file"
    
por 10.06.2015 / 11:51
5

Se a entrada for um arquivo regular lseekable :

Com o GNU grep :

{ grep  -xFm1 'dog 123 4335' >&2
  cat; } <infile 2>/dev/null >outfile

com sed :

{ sed -n '/^dog 123 4335$/q'
  cat; } <infile >outfile

Um GNU grep chamado w / a opção -m sairá da entrada na partida - e deixará sua entrada (lseekable) fd imediatamente após o ponto em que encontrou sua última correspondência. Portanto, chamar grep w / -m1 localiza a primeira ocorrência de um padrão em um arquivo e deixa o deslocamento de entrada exatamente no lugar certo para cat gravar tudo seguindo a primeira correspondência do padrão em um arquivo para stdout. / p>

Mesmo sem um GNU grep , você pode fazer exatamente a mesma coisa com um sed compatível com POSIX - quando sed q uits é especificado para deixar seu deslocamento de entrada exatamente onde ele ocorre. No entanto, o GNU sed não é compatível com os padrões e, portanto, o acima provavelmente não funcionará com um GNU sed , a menos que você o chame com sua opção -u .

    
por 10.06.2015 / 13:25
4

Uma maneira de usar o awk:

awk 'NR==FNR{a[$0];next}f;($0 in a){f=1}'  file2 file1

em que file2 contém seus padrões de pesquisa. Primeiro, todo o conteúdo do arquivo2 é armazenado na matriz "a". Quando o arquivo1 é processado, cada linha é verificada no array e impressa somente se não estiver presente.

    
por 23.11.2012 / 08:37
4

Minha resposta para a pergunta no assunto, sem armazenar o padrão em um segundo arquivo. Aqui está o meu arquivo de teste:

$ cat animals.txt 
cat 13123 23424 
deer 2131 213132
bear 2313 21313
dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

sed do GNU:

 $ sed '0,/^dog 123 4335$/d' animals.txt 
 cat 13123 23424 
 deer 2131 213132
 bear 2313 21313

Perl:

$ perl -ne 'print unless 1.../^dog 123 4335$/' animals.txt
cat 13123 23424 
deer 2131 213132
bear 2313 21313

Variante Perl com padrão em um arquivo:

$ cat pattern.txt 
dog 123 4335
$ perl -ne 'BEGIN{chomp($p=(<STDIN>)[0])};print unless 1../$p/;' animals.txt < pattern.txt
cat 13123 23424 
deer 2131 213132
bear 2313 21313
    
por 09.10.2014 / 13:49
1

How to print all lines after a match up to the end of the file?

Outra forma de colocar é "como deletar todas as linhas desde a 1ª até a partida (inclusive)", e isso pode ser sed -written como:

sed -e '1,/MATCH PATTERN/d'
    
por 24.09.2015 / 22:17
0

Como o awk não é expressamente proibido, aqui está minha oferta assumindo que 'gato' é a correspondência.

awk '$0 ~ /cat/ { vart = NR }{ arr[NR]=$0 } END { for (i = vart; i<=NR ; i++) print arr[i]  }' animals.txt
    
por 23.11.2012 / 11:25