Opróżnij zawartość pliku

220

Znam trzy metody usuwania wszystkich wpisów z pliku.

Oni są

  • >filename
  • touch filename
  • filename < /dev/null

Z tych trzech >filenamenajbardziej nadużywam, ponieważ wymaga to najmniejszej liczby naciśnięć klawiszy.

Chciałbym jednak wiedzieć, która z nich jest najbardziej wydajna (jeśli istnieją bardziej wydajne metody) w odniesieniu do dużych plików dziennika i małych plików.

Jak działają te trzy kody i usuwają zawartość?

debal
źródło
24
Co truncate -s 0 filename?
Martin Thoma,
Bardzo podobny do różnicy między cat i '>', aby wyzerować plik, w którym znajdziesz więcej informacji.
Stéphane Chazelas
Pierwszy zadziała tylko, jeśli zostanie wywołany z linii poleceń bash, ale nie zadziała, jeśli zostanie wykonany w pliku .sh
Marco Marsala,
8
touch nie usuwa zawartości, ale zmienia czas dostępu do pliku. Czyni utworzyć pusty plik jeśli żaden istniał.
hbogert

Odpowiedzi:

293

W rzeczywistości druga forma touch filenamenie usuwa niczego z pliku - tworzy pusty plik, jeśli nie istnieje, lub aktualizuje datę ostatniej modyfikacji istniejącego pliku.

A trzeci filename < /dev/nullpróbuje uruchomić nazwę pliku z danymi /dev/nullwejściowymi.

cp /dev/null filename Pracuje.

Jeśli chodzi o wydajność, najbardziej wydajna byłaby truncate -s 0 filename; patrz tutaj: http://linux.die.net/man/1/truncate .

W przeciwnym razie, cp /dev/null filenamelub > filenameoba są w porządku. Obie otwierają, a następnie zamykają plik, korzystając z ustawienia obcinania przy otwieraniu. cpotwiera się również /dev/null, dzięki czemu jest nieznacznie wolniejszy.

Z drugiej strony truncateprawdopodobnie byłby wolniejszy niż > filenamepodczas uruchamiania ze skryptu, ponieważ uruchomienie komendy truncate wymaga, aby system otworzył plik wykonywalny, załadował go i uruchomił.

popiół
źródło
9
Dlaczego więc uważasz, że truncatejest to najbardziej wydajny?
Stéphane Chazelas,
7
Operacja obcinania wykorzystuje wywołanie systemowe ftruncate () lub truncate (), które nie przeszkadza w otwarciu pliku. Unika także wywołania systemowego close (), które > filenamemuszą wywoływać procesory i metody.
popiół
3
Właściwie to (przynajmniej GNU) robi open + ftruncate + close (oprócz wielu wywołań systemowych, aby się załadować i zainicjować), ponieważ i tak musiałby utworzyć plik, gdyby nie istniał i truncate(2)tego nie robi.
Stéphane Chazelas,
Jeśli użyjemy touch filename, czy i-węzeł pozostanie taki sam (pod warunkiem, że wcześniej istniał plik)?
pMan
1
@pMan tak, możesz spróbować i sprawdzić za pomocąls -i
terdon
43

Inną opcją może być:

echo -n > filename

Ze strony podręcznika użytkownika echo:

-n Do not print the trailing newline character.

Arturo Herrero
źródło
Jak mogę ustawić rozmiar? Powiedz, czy chcę 30000 znaków zerowych?
Użytkownik
3

Istnieje wbudowane polecenie „:”, które może być dostępne w sh, csh, bash i innych, które można łatwo wykorzystać z przekierowującym operatorem wyjściowym, >skracając plik:

#!/usr/bin/env bash
:> filename

Podoba mi się to, że nie potrzebuje żadnych zewnętrznych poleceń, takich jak „echo” itp.

Jedną wielką zaletą obcięcia plików zamiast ich usuwania / odtwarzania jest to, że działające aplikacje, które działają z tym plikiem (np. Ktoś tworzy tail -f filenameoprogramowanie monitorujące lub ...) nie muszą go ponownie otwierać. Mogą po prostu kontynuować korzystanie z filedescriptor i pobierać wszystkie nowe dane.

Mirko Steiner
źródło
man bashopisuje :wbudowaną powłokę jako niedziałającą.
Haxiel,
Tak, i przekierowujesz to za pomocą >do pliku, który tworzy plik, jeśli nie istnieje, a jeśli istnieje, przycinasz go do zera. Lepiej powiedz: używasz tego, :aby nic nie robić, i używać >do przekierowywania niczego do pliku i obcinania go.
Mirko Steiner,
1
Dlaczego chcesz to zrobić? > filewystarczy obciąć plik. Nie potrzebujesz żadnego polecenia, tylko operator przekierowania.
terdon
1
czasami > filenamenie działa. na przykład w zsh. ale : > filenamenadal działa.
CS Pei,
Bash i sh wydają się lubić, > myfileale np. Błędy csh z: Niepoprawne polecenie null.
Mirko Steiner,