Ho bisogno di aiuto con Grep per iniziare da una sezione


8

Ho alcuni file di testo da cui desidero grep una sezione di codice. L'obiettivo che sto cercando di raggiungere è iniziare la visualizzazione da una determinata riga e quindi poter leggere qualsiasi cosa al di sotto di essa. Per esempio. Nel testo seguente, come posso visualizzare il file di testo nel punto iniziale giallo. Voglio visualizzare il contenuto di "giallo" e tutto ciò che sta sotto, indipendentemente da quale sia quel contenuto.

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

Risposte:


9

AWK Use AWK: è il più semplice in quanto può ottenere:

awk '/yellow/,0' textfile.txt

Esecuzione del campione

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

grep

Puoi anche usare grepcon l' --after-contextopzione, per stampare un certo numero di righe dopo la partita

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

Per l'impostazione automatica del contesto, è possibile utilizzare $(wc -l textfile.txt). L'idea di base è che se si dispone di una prima riga come corrispondenza e si desidera stampare tutto dopo quella corrispondenza, è necessario conoscere il numero di righe nel file meno 1. Fortunatamente, --after-contextnon verranno generati errori sul numero di linee, quindi potresti dargli un numero completamente al di fuori dell'intervallo, ma nel caso non lo sapessi, lo farà il numero totale di linee

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

Se si desidera abbreviare il comando --after-contextè la stessa opzione di -Ae $(wc -l textfile.txt), si espanderà al numero di righe seguito dal nome del file. In questo modo digiti textfile.txtuna sola volta

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

Pitone

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')

O in alternativa senza printablebandiera

#!/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()

È possibile semplificare il grepcomando a grep "yellow" -A $(wc -l textfile.txt).
Byte Commander

@ByteCommander sì, si può fare anche. Ho usato l'opzione completa per chiarezza
Sergiy Kolodyazhnyy il

1
@ByteCommander Che bel trucco. Sfortunatamente funziona solo perché non ci sono spazi nel nome del file.
Kasperd,

@kasperd Oh sì, hai ragione. In tal caso, dovresti ricorrere al comando originale di Serg grep "yellow" -A $(wc -l < "my colors.txt") "my colors.txt".
Byte Commander

5

Puoi farlo tramite:

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

dove "file" è il nome del file che contiene il testo.


Le grandi menti pensano allo stesso modo> :)
Sergiy Kolodyazhnyy il

5

No grep, ma usando sed:

sed -n '/^yellow$/,$p' file
  • -n: inibisce la stampa
  • /^yellow$/,$: intervallo di indirizzi che va dalla prima occorrenza di una riga corrispondente esattamente yellowall'ultima riga inclusa
  • p: stampa le linee nell'intervallo di indirizzi
% sed -n '/^yellow$/,$p' file
yellow
red
orange
more orange
more blue
this is enough

5

In ritardo alla festa :)

Utilizzando grep:

grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
  • -P ci consente di utilizzare Regex compatibile con Perl

  • -z rende il file di input separato da ASCII NUL, piuttosto che da newline

  • -o prende solo la porzione desiderata

  • (?s)è il modificatore DOTALL, ci consente di abbinare newline usando il token .(qualsiasi carattere)

  • In \n\K, \ncorrisponde a una nuova riga, \Kscarta la corrispondenza

  • yellow\n.*corrispondenze yellowseguite da una nuova riga e tutto ciò che viene anche selezionato e mostrato nell'output.

Esempio:

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

Usando poco python:

#!/usr/bin/env python2
with open('file.txt') as f:
    lines = f.readlines()
    print ''.join(lines[lines.index('yellow\n'):])
  • lines è l'elenco che contiene tutte le righe del file (anche con le nuove righe finali)

  • lines.index('yellow\n')ci dà l'indice più basso di linesdove yellow\nsi trova

  • lines[lines.index('yellow\n'):]utilizzerà la suddivisione in elenchi per ottenere la parte a partire dalla yellow\nfine

  • join unirà gli elementi dell'elenco per l'output come stringa


Bello, ma dovresti dire che il codice Python trova solo intere righe uguali a "giallo", non rileva ad esempio linee come "più giallo".
Byte Commander

@ByteCommander Dall'esempio di OP penso che sia chiaro che vogliono abbinarsi solo yellownella linea..anche se non è così, allora abbiamo bisogno di cambiare l' python
ego di qualcuno

Si certo. Non era comunque una critica, solo un suggerimento per migliorare la risposta. Qualcun altro che legge questo potrebbe supporre che il codice funzioni come grepe non corrisponda solo a linee complete. Ho votato a favore.
Byte Commander

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.