Preciso de ajuda com o Grep para começar em uma seção


8

Eu tenho alguns arquivos de texto que eu quero grep uma seção de código. O objetivo que estou tentando alcançar é iniciar a visualização em uma determinada linha e poder ler qualquer coisa abaixo dela. Por exemplo. No texto abaixo, como visualizo o arquivo de texto no ponto inicial em amarelo. Quero ver o conteúdo de "amarelo" e tudo o que está abaixo dele, independentemente do conteúdo.

green
blue
cyan
magenta
purple
brown
yellow
red
orange
more orange
more blue
this is enough

Respostas:


9

Uso AWKAWK - é o mais simples possível:

awk '/yellow/,0' textfile.txt

Amostra de execução

$ awk '/yellow/,0' textfile.txt                                
yellow
red
orange
more orange
more blue
this is enough

Grep

Você também pode usar grepcom a --after-contextopção imprimir uma certa quantidade de linhas após a partida

grep 'yellow' --after-context=999999  textfile.txt

Para configuração automática de contexto, você pode usar $(wc -l textfile.txt). A idéia básica é que, se você tiver uma primeira linha como uma correspondência e quiser imprimir tudo depois dessa correspondência, precisará saber o número de linhas no arquivo menos 1. Felizmente, --after-contextnão lançará erros sobre o número de linhas, para que você possa dar um número completamente fora do intervalo, mas, caso não o conheça, o número total de linhas será suficiente

$ grep 'yellow' --after-context=$(wc -l < textfile.txt) textfile.txt
yellow
red
orange
more orange
more blue
this is enough

Se você deseja reduzir, o comando --after-contexté a mesma opção que -Ae $(wc -l textfile.txt), será expandido para o número de linhas seguidas pelo nome do arquivo. Dessa forma, você digita textfile.txtapenas uma vez

grep "yellow" -A $(wc -l textfile.txt)

Pitão

skolodya@ubuntu:$ ./printAfter.py textfile.txt                                 
yellow
red
orange
more orange
more blue
this is enough

DIR:/xieerqi
skolodya@ubuntu:$ cat ./printAfter.py                                          
#!/usr/bin/env python
import sys

printable=False
with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
           printable=True
        if printable:
           print line.rstrip('\n')

Ou, alternativamente, sem printablebandeira

#!/usr/bin/env python
import sys

with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
          for lines in f: # will print remaining lines
             print lines.rstrip('\n')
          exit()

Você pode simplificar o grepcomando para grep "yellow" -A $(wc -l textfile.txt).
Byte Commander

@ByteCommander sim, também pode ser feito. Apenas usada completa opção para maior clareza
Sergiy Kolodyazhnyy

1
@ByteCommander Que hack adorável. Infelizmente, ele só funciona porque não há espaços no nome do arquivo.
kasperd

@kasperd Oh sim, você está certo. Nesse caso, você teria que voltar ao comando original de Serg grep "yellow" -A $(wc -l < "my colors.txt") "my colors.txt".
Byte Commander

5

Você pode fazer isso:

awk '/yellow/{f=1}f' file

onde "arquivo" é o nome do arquivo que contém seu texto.


Grandes mentes pensam da mesma forma> :)
Sergiy Kolodyazhnyy

5

Não grep, mas usando sed:

sed -n '/^yellow$/,$p' file
  • -n: inibe a impressão
  • /^yellow$/,$: intervalo de endereços que vai da primeira ocorrência de uma linha que corresponde exatamente yellowà última linha, inclusive
  • p: imprime as linhas no intervalo de endereços
% sed -n '/^yellow$/,$p' file
yellow
red
orange
more orange
more blue
this is enough

5

Tarde para a festa :)

Usando grep:

grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
  • -P permite usar Regex compatível com Perl

  • -z torna o arquivo de entrada separado por ASCII NUL, em vez da nova linha

  • -o leva apenas a parte desejada

  • (?s)é o modificador DOTALL, permite corresponder nova linha usando token .(qualquer caractere)

  • Em \n\K, \ncorresponde a uma nova linha, \Kdescarta a correspondência

  • yellow\n.*correspondências yellowseguidas por uma nova linha e tudo depois disso também é selecionado e mostrado na saída.

Exemplo:

% grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
yellow
red
orange
more orange
more blue
this is enough

Usando pouco python:

#!/usr/bin/env python2
with open('file.txt') as f:
    lines = f.readlines()
    print ''.join(lines[lines.index('yellow\n'):])
  • lines é a lista que contém todas as linhas do arquivo (com novas linhas à direita também)

  • lines.index('yellow\n')nos dá o menor índice de linesonde yellow\né encontrado

  • lines[lines.index('yellow\n'):]usará o fatiamento de lista para obter a parte que vai do início ao yellow\nfim

  • join juntará os elementos da lista para produzir como uma sequência


Bom, mas você deve mencionar que o código Python encontra apenas linhas inteiras iguais a "amarelo", ele não detecta, por exemplo, linhas como "mais amarelo".
Byte Commander

@ByteCommander partir do exemplo de OP eu acho que é claro que eles querem corresponder apenas yellowno line..also se isso não for o caso, então é preciso mudar o pythonde um algo ..
heemayl

Sim claro. De qualquer forma, isso não foi uma crítica, apenas uma dica para melhorar a resposta. Alguém mais lendo isso pode assumir que o código funciona como grepe não corresponde apenas às linhas completas. Eu votei a favor.
Byte Commander

4

Como a pergunta se refere à visualização do arquivo, sempre há o bom e velho

less +/yellow file

Não sabia que lesspode fazer isso. Muito agradável !
Sergiy Kolodyazhnyy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.