2010-05-26 5 views
32

Es gibt oft Zeiten grep -n whatev Datei zu finden, was ich suche. Sagen Sie der AusgangWie man bestimmte Zeilenbereiche einer Datei "grep"

1234: whatev 1 
5555: whatev 2 
6643: whatev 3 

ist Wenn ich dann zwischen 1234 und 5555 extrahieren will nur die Linien, ist es ein Werkzeug, das zu tun? Für statische Dateien habe ich ein Skript, das wc -l der Datei tut und dann die Mathematik, um es mit Schwanz & Kopf zu trennen, aber das funktioniert nicht so gut mit Protokolldateien, die ständig geschrieben werden.

+4

Siehe http://stackoverflow.com/questions/83329/how-can-i-extract-a-range-of-lines-from-a-text- file-on-unix – GreenMatt

Antwort

53

Verwenden Sie sed wie unter http://linuxcommando.blogspot.com/2008/03/using-sed-to-extract-lines-in-text-file.html erwähnt. Verwenden Sie zum Beispiel

sed '2,4!d' somefile.txt 

, um von der zweiten Zeile bis zur vierten Zeile von somefile.txt zu drucken. (Und vergessen Sie nicht http://www.grymoire.com/Unix/Sed.html zu überprüfen, sed ein wunderbares Werkzeug ist.)

+3

Ein nützliches Nachfolgebit von Informationen ist, wie man die Zeilennummern dem sed-Ergebnis voranstellt ... pipe es in nl wie folgt: 'sed ''" $ start "','" $ end "' ! d 'somefile.txt | nl -ba -v $ start' – phyatt

0

diese in einer Datei speichern, und es ausführbar machen:

#!/bin/bash 
start=`grep -n $1 < $3 | head -n1 | cut -d: -f1; exit ${PIPESTATUS[0]}` 
if [ ${PIPESTATUS[0]} -ne 0 ]; then 
    echo "couldn't find start pattern!" 1>&2 
    exit 1 
fi 
stop=`tail -n +$start < $3 | grep -n $2 | head -n1 | cut -d: -f1; exit ${PIPESTATUS[1]}` 
if [ ${PIPESTATUS[0]} -ne 0 ]; then 
    echo "couldn't find end pattern!" 1>&2 
    exit 1 
fi 

stop=$(($stop + $start - 1)) 

sed "$start,$stop!d" < $3 

die Datei ausführen mit Argumenten (Hinweis, dass das Skript nicht funktioniert Griff Leerzeichen in Argumenten):

  1. grep Muster
  2. Starten Stoppen grep Muster
  3. Dateipfad

mit Ihrem Beispiel zu verwenden, verwenden Argumente: 1234 5555 myfile.txt

Inklusive Linien mit Start- und Stoppmustern.

+3

downvoters, bitte erklären –

15

Der folgende Befehl wird tun, was Sie für "extrahieren Sie die Zeilen zwischen 1234 und 5555" in someFile.

sed -n '1234,5555p' someFile

+1

Ich musste '/' Trennzeichen hinzufügen, um es zu arbeiten: 'sed -n '/ 1234 /,/5555/p' someFile' – JB0x2D1

+0

Ziemlich praktisch :) +1 –

0

Wenn Sie Linien statt Linie wollen reicht, können Sie es mit Perl tun: zB. wenn Sie Linie erhalten möchten 1, 3 und 5 aus einer Datei, sagen/etc/passwd:

perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd 
+2

FYI, das '$ l' ist" Dollar el "nicht" Dollar eins ". Ein eher perliger (d. H. Kürzerer) Befehl ist "perl -ne" if ($. ~~ [1,3,5]) {print} '/ etc/passwd'. –

3

Wenn ich richtig verstehe, Sie wollen ein Muster zwischen zwei Zeilennummern zu finden. Der awk Einzeiler konnte

awk '/whatev/ && NR >= 1234 && NR <= 5555' file 

sind Sie brauchen nicht grep gefolgt von sed zu laufen.

Perl Einzeiler:

perl -ne 'if (/whatev/ && $. >= 1234 && $. <= 5555') {print}' file 
Verwandte Themen