odczytać określony zakres linii z pliku

15

Mam plik zawierający 100000 linii, w jaki sposób mogę uzyskać linie z linii nr 5555 do linii nr 7777 pod Linuksem.

Dzięki za wszystko.


źródło
1
@ibrahim, zastanów się nad odpowiedzią Kyle'a (zaznaczając zielony znacznik wyboru po lewej), jeśli to ci pomogło
Jonik
możesz sprecyzować, czy chcesz korzystać z sed, czy inne narzędzia są w porządku.
Manu H
Trochę badań rzuca przynajmniej stackoverflow.com/questions/83329/…
sancho.s Przywróć Monikę

Odpowiedzi:

22
sed '5555,7777!d' <filename>

Spowoduje to wydrukowanie wierszy 5555-7777 pliku włącznie.

Dennis wysłał następujące, które zgadzam się powinny być szybsze:

sed '5555,7777p; 7778q' filename

Następujące dowody, że powinno być szybciej:

$ n=1
$ while [[ n -le 100000 ]]; do echo $n >> sedtest2; n=$((n + 1)); done
$ strace -e trace=read -o sed1 sed '5555,7777!d' sedtest2
$ strace -e trace=read -o sed2 sed '5555,7777p; 7778q' sedtest2
$ wc -l sed1
149 sed1
$ wc -l sed2
14 sed1

Tylko w Bash (dla zabawy):

n=1
while read line; do 
    if [[ ($n -ge 5555) && ($n -le 7777)  ]]; then 
        echo $line
    elif [[ $n -gt 7777 ]]; then
        break
    fi 
    n=$(( $n + 1 ))
done < file
Kyle Brandt
źródło
Myślę, że $n -gt 3powinieneś być 7777? Możesz także zrobić, if (( n >= 5555 ))aby uzyskać bardziej „naturalnie” wyglądające operatory porównania numerycznego (i możliwość pominięcia znaku dolara). I możesz zrobić ((n++)).
Wstrzymano do odwołania.
16

Rezygnacja po zakończeniu może przyspieszyć:

sed -n '5555,7777p; 7778q' input_file
Wstrzymano do odwołania.
źródło
1
+1, powinno być szybsze, zaktualizowałem mój post, aby pokazać dlaczego.
Kyle Brandt
7

Każdy z nich powinien działać;

  • sed -n ' numer początkowy , numer końcowy p'
  • awk 'NR> = numer początkowy && NR <= numer końcowy '

Nawiasem mówiąc, świetne pytanie;)

Siekacz 3
źródło
1

Odkryłem, że opcja sed nie działała na pliku mysqldump, zgaduję ze względu na obsługę cytowanych linii lub znaków wielobajtowych. głowa i ogon przecinają go przy użyciu tych samych numerów linii co grep, czego potrzebowałem. Aby uzyskać linie od $ j do $ k, potrzebujesz:

x=$(( $k - $j + 1 ))
tail -n +$j filename | head -${x} 
Dave Crooke
źródło