Usuń pierwszą linię pliku


110

Jak mogę usunąć pierwszy wiersz pliku i zachować zmiany?

Próbowałem tego, ale usuwa całą zawartość pliku.

$sed 1d file.txt > file.txt

Odpowiedzi:


81

Powodem, dla którego file.txt jest pusty po tym poleceniu, jest kolejność, w jakiej powłoka wykonuje różne czynności. Pierwszą rzeczą, która dzieje się z tą linią, jest przekierowanie. Plik „file.txt” zostaje otwarty i obcięty do 0 bajtów. Następnie uruchamia się polecenie sed, ale w tym momencie plik jest już pusty.

Istnieje kilka opcji, większość z nich polega na zapisaniu do pliku tymczasowego.

sed '1d' file.txt > tmpfile; mv tmpfile file.txt # POSIX
sed -i '1d' file.txt # GNU sed only, creates a temporary file

perl -ip -e '$_ = undef if $. == 1' file.txt # also creates a temporary file

2
Z BSD sedmożesz korzystać sed -i .bak '1d' file.txt.

1
czy istnieje sposób, który nie obejmuje pliku tymczasowego? W każdym razie to wystarczy. Wielkie dzięki!
kickass13

@ kickass13 prawdopodobnie przy użyciu edytora tekstu, takiego jak ed.
jordanm

6
edKomenda będzie: printf "%s\n" 1d w q | ed file.txt(I serce ed)
Glenn Jackman

1
@jonayreyes-exec sed -i '1d' {} \;
jordanm

141

Alternatywną, bardzo lekką opcją jest po prostu „ogonowanie” wszystkiego oprócz pierwszej linii (może to być łatwy sposób na usunięcie nagłówków plików):

# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout

Śledząc @Evan Teitelman, możesz:

tail -n +2 file.txt | sponge file.txt

Aby uniknąć pliku tymczasowego. Inną opcją może być:

echo "$(tail -n +2 file.txt)" > file.txt

I tak dalej. Testowanie ostatniego:

[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5

[user@work ~]$ echo "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5
[user@work ~]$ 

Ups, zgubiliśmy nowy wiersz (na komentarz @ 1_CR poniżej), spróbuj zamiast tego:

printf "%s\n\n" "$(tail -n +2 file.txt)" > file.txt

[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5

[user@work ~]$ printf '%s\n\n' "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5  

[user@work ~]$ 

Wracając do sed, spróbuj:

printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt

a może

echo -e "$(sed '1d' file.txt)\n" > file.txt

Aby uniknąć skutków ubocznych.


Właśnie wypróbowałem to na moim systemie Fedora i wynik jest powyżej. Masz rację - dziękuję za zwrócenie na to uwagi.
AsymLabs

tailSztuczka pracował dla mnie (trwało mniej niż 3 sekundy na pliku 130MB). Dzięki!
elo80ka,

echo "$(tail -n +2 file.txt)" > file.txtjest idealną odpowiedzią.
Alex Raj Kaliamoorthy,

Dziękuję Ci! echo „$ (tail -n +2 file.txt)”> file.txt działa dla mnie jak urok!
Arsenii

16

Również przyjrzeć się spongez moreutils. spongeprzesiąka w danych ze standardowego wejścia, dopóki koniec zapisu standardowego wejścia nie zamknie się przed zapisaniem do pliku. Używa się go tak:

sed '1d' file.txt | sponge file.txt

14

Ten temat jest interesujący, więc testuję test porównawczy na 3 sposoby:

  1. sed '1d' d.txt > tmp.txt
  2. tail -n +2 d.txt > tmp.txt
  3. sed -i '1d' d.txt

Pamiętaj, że celem d.txtjest plik o pojemności 5,4 GB

Uzyskaj wynik:


run 1 : sed '1d' d.txt > r1.txt
14s
run 2 : tail -n +2 d.txt > r2.txt
20s
run 3 : sed -i '1d' d.txt
88s

Wniosek: wydaje się, że poniżej jest najszybszy sposób:

sed '1d' file.txt > tmpfile; mv tmpfile file.txt


Twoja sed '1d' d.txtmetoda nie zawierała (a przynajmniej tak się wydaje, czytając testy) mvpolecenia. W moich testach na FreeBSD z plikiem 20 MB sed -ibył najszybszy.
Sopalajo de Arrierez

9

exmoże być używany do prawdziwej edycji w miejscu, która nie wymaga pliku tymczasowego

ex -c ':1d' -c ':wq' file.txt

2
ex używa pliku tymczasowego. strace -e open ex -c ':1d' -c ':wq' foo. ex obcina oryginalny plik plikiem tymczasowym, gdzie jako opcja -i w GNU sed zastępuje oryginał plikiem tymczasowym. Nie jestem pewien, jak działa sed BSD.
llua

@llua, masz rację. Zauważyłem to również, ale później
iruvar,

3

Najkrótszym i najprostszym sposobem usunięcia pierwszego wiersza z pliku sedjest:

$ sed -i -n -e '2,$p' file.txt

3

Możesz używać Vima w trybie Ex:

ex -s -c '1d|x' file.txt
  1. 1 znajdź pierwszą linię

  2. d usunąć

  3. x Zapisz i zamknij


0

To polecenie usunie 1 linię i zapisze jako „plik.txt”.

sed '1d' file.txt  > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt

0

Aby usunąć wiersz praticiler w pliku

  1. Usuń pierwszą linię

Plik „1d” Sed

  1. Usuń pierwszą i trzecią linię

Plik „1d3d” Sed

Usuń charecter w linii

1 Usuń Pierwsze dwie karty w linii

Plik Sed /^..// 'Sed

2 Usuń dwie ostatnie linie chrectercin

Plik Sed / .. £ //

3 Usuń pusty wiersz

Plik Sed '/ ^ £ / d'


4
Czy Brytyjczycy odzyskali kolonie? Ostatni raz patrzyłem £$.
G-Man,

£ wskazał znak
Dollera


-2

plik kota 01 | sed -e „1,3d”

// pokaż zawartość w pliku 01, ale usuń pierwszy i trzeci wiersz


2
wydane przez ciebie polecenie sed usunie wiersze 1, 2 i 3.
icarus

1
Usuwa to więcej, niż jest wymagane, i nie „zachowuje zmian”
Jeff Schaller
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.