2011-04-19 13 views
13

Widziałem wiele odmian, bardzo zdezorientowany, w jaki sposób rozwiązać te 3 problemy.Usuń linie z pliku z SED lub AWK

  1. usuwając wszystkie wiersze z wyjątkiem pierwszego z pliku
  2. usunięcie wiersza z pliku z numerem linii
  3. usuwanie wierszy z pliku z zakresu numerów linii

Odpowiedz

24

Stosując SED:

Delete 1. linia:

sed '1d' file-name 

Usuń 10. wiersz:

sed '10d' file-name 

Delete linia nr 5 do 10

sed '5,10d' file-name 

Wszystkie powyższe polecenia sed napiszę wyjście na standardowe wyjście, które można przekierować do innego pliku, jeśli chcesz lub korzystania -i banderą sed, aby wstawić edytować plik.

+1

* aby usunąć wszystkie linie, ale pierwszy *, 'sed '2 $ d' filename' lub' sed '1! d' plikN ame', lub 'sed -n '1p' nazwa pliku'. – Beta

+0

@ Beta, pierwsze dwa są dokładnie w porządku, ale trzeci wydrukuje tylko pierwszą linię. – dubiousjim

+1

@dubiousjim: "Drukuj tylko pierwszy wiersz" jest takie samo, jak "usuń wszystkie linie oprócz pierwszego", dlatego też "sed -n" 1p'' również jest poprawne. – anubhava

7

Z awk:

# delete line 1 
awk 'NR == 1 {next} {print}' file 

# delete line number stored in shell variable $n 
awk -v n=$n 'NR == n {next} {print}' file 

# delete between lines $a and $b inclusive 
awk -v m=$a -v n=$b 'm <= NR && NR <= n {next} {print}' file 

Aby zapisać kilka znaków, {print} może być zastąpiony tylko z 1

Aby zastąpić oryginalny plik, trzeba zrobić coś takiego

awk '...' file > tmpfile && mv tmpfile file 
+0

jak mogę uzyskać wyjście awk, aby się nie wyświetlać? – bluetickk

+0

OK, działa, ale linie są tylko drukowanie i nie zapisywanie do pliku? – bluetickk

+0

@bluetickk, zaktualizowałem moją odpowiedź –

0

możesz po prostu użyć basha, jeśli masz go w systemie. Podstawową ideą jest ustawienie liczby i zwiększenie tej liczby podczas iterowania pliku.

1) usunięcie wszystkich rzędów, z wyjątkiem pierwszego z pliku

read -r line < file; echo "$line" > temp && mv temp file 

2) Usuwanie wiersza z pliku z numerem linii

declare -i count=0 
while read -r line 
do 
    ((count++)) 
    case "$count" in 
    10) continue;; 
    *) echo "$line";; 
    esac 
done <file> temp && mv temp file 

3) Usuwanie wierszy z pliku z zakresu z numerami linii przykład od 10 do 20

declare -i count=0 
while read -r line 
do 
    ((count++)) 
    if (($c < 10 && $c > 20));then 
    echo "$line";; 
    fi 
done <file> temp && mv temp file 
+0

Sposób, w jaki go używasz, powoduje, że 'read -r' nadal usuwa początkowe i końcowe spacje. Musisz wykonać 'IFS = read -r line'.Co więcej, zwróć uwagę, że ze skryptu powłoki ta metoda jest szybsza w przypadku małych plików, ponieważ unika rozwidlenia, ale wolniej w przypadku dużych plików, ponieważ "odczyt" jest z natury nieefektywny i zwykle odczytuje jeden bajt na raz lub robi jedno odczytane i wywołanie LESEK na inwokację i przetwarzanie ciągów w bashu wydaje się być nieefektywne (mniej w innych powłokach). – jilles

+0

@jilles, dziękuję zapomniałem o IFS = w tych przypadkach. Tak, wiem, że 'read' jest nieefektywne w przypadku dużych plików z' bash'. Jeśli pliki OP mają duże rozmiary, a wydajność to problem, użyj lepszego narzędzia. –

Powiązane problemy