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
kickass13
źródło

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
Jordan
źródło
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.

AsymLabs
źródło
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

źródło
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

waue0920
źródło
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
iruvar
źródło
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
rozgwiazdy
źródło
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

Steven Penny
źródło
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
Ritesh Singh
źródło
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'

Vivek Parikh
źródło
4
Czy Brytyjczycy odzyskali kolonie? Ostatni raz patrzyłem £$.
G-Man,
£ wskazał znak
Dollera
0

Przydałby się do tego vim:

vim -u NONE +'1d' +wq! /tmp/test.txt
Hongbo Liu
źródło
-2

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

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

użytkownik215264
źródło
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