Opróżnianie zawartości pliku tekstowego

16

Mam plik tekstowy w moim katalogu domowym, który regularnie otrzymuje dane za pośrednictwem zadania cron. Ponieważ zadanie cron zapewnia dane dynamiczne, chciałbym również ustawić zadanie cron w celu opróżnienia zawartości pliku (plik musi nadal istnieć). Nie potrzebuję pomocy z cronem, tylko polecenie, które może pomóc w opróżnieniu pliku.

sosytee
źródło
5
Alternatywnie: tail -n +1000 file.txt > file.txtnależy usunąć 1000 wierszy i zachować najnowsze wiersze w pliku (nigdy nie wiadomo, kiedy może być potrzebny jakiś najnowszy rekord do śledzenia czegoś).
Rinzwind
2
To jest rzeczywiście lepsza opcja niż czyszczenie pliku w zaplanowanym czasie.
Bruno Pereira,
1
@Rinzwind, to nie zadziała, ponieważ plik zostanie obcięty, zanim tail spróbuje go odczytać. Musisz przekierować do nowego pliku, a następnie zastąpić oryginał nowym.
psusi
Prawda @psusi :) tam musi być dodatkowe przekierowanie.
Rinzwind

Odpowiedzi:

28

Najprostszy sposób:

> filename

Jest to mniej oczywisty sposób i prawdopodobnie mniej czytelny w skrypcie powłoki przez innych, ale to wszystko, czego potrzebujesz.

Ponieważ >tak naprawdę nie jest to naprawdę polecenie (jest wbudowane w bash), którego nie możesz użyć:

sudo > filename

gdy nie masz uprawnień do tego pliku. Ale możesz użyć:

sudo bash -c "> filename"
Radu Rădeanu
źródło
jakie uprawnienia należy zmienić, ponieważ mówi, że odmówiono zezwolenia, zrobiłem już chmod 755 do pliku, czy też powinienem zrobić nowy post (mam na myśli pytanie o uprawnienia)
sosytee 12.12.2013
@sosytee Zobacz moje nowe zmiany.
Radu Rădeanu,
1
@sosytee Oczywiście możesz, ale użyj, sudo crontab -eaby dodać zadanie cron dla roota, a nie dla ciebie. Lub zmienić uprawnienia pliku na 766 (lub 666), a nie do 755: sudo chmod 766 filename. Więcej informacji: codex.wordpress.org/Changing_File_Permissions
Radu Rădeanu
1
truncate filenamejest trochę czystszy i prostszy niż przekierowywanie pustych danych wyjściowych do pliku i nie napotyka problemów sudo.
psusi
1
@psusi truncate -s 0 filenamerzeczywiście może załatwić sprawę . Możesz dodać to jako odpowiedź.
Radu Rădeanu,
19

W tym celu stworzono narzędzie:

truncate -s 0 filename

Spowoduje to wyczyszczenie zawartości, ale nadal będzie to ten sam plik (i- węzeł pozostaje taki sam).

Jest to ważne, ponieważ niektóre programy trzymają uchwyt pliku „przez i-węzeł”. Załóżmy, że „opróżniłeś” plik przy użyciu naiwnej metody usuwania i ponownego tworzenia pliku. Niektóre programy mogą nadal trzymać uchwyt starego pliku (ze starą zawartością), nawet jeśli nie jest już widoczny zwykłymi środkami ls.

Niektóre linki do bardziej szczegółowych informacji na końcu tej odpowiedzi.


Innym sposobem, może łatwiejszym do zapamiętania:

echo -n > filename

To także utrzymuje ten sam i-węzeł.

Należy zauważyć, że zarówno truncatei echo -nnie są zdefiniowane przez POSIX .

W celu zachowania zgodności z POSIX cat /dev/null:

cat /dev/null > filename

Jeszcze inny sposób, bardziej niejasny i prawdopodobnie nie zależny od powłoki:

> filename

Jeśli plik do obcięcia wymaga uprawnień administratora do zapisu, następujące linie nie będą działać zgodnie z oczekiwaniami:

sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename

Dzieje się tak, ponieważ przekierowanie jest wykonywane przez powłokę jeszcze przed uruchomieniem sudo. Oznacza to, że dostęp do zapisu do pliku odbywa się przy użyciu uprawnień użytkownika, który uruchamia powłokę, a nie uprawnień, które zostaną przyznane przez sudo.

Obejściem tego problemu jest odroczenie przekierowania do powłoki wykonanej przy użyciu uprawnień sudo:

sudo sh -c "echo -n > filename"

Korzystanie z truncateciebie nie wymaga takiego obejścia, ponieważ dostęp do zapisu nie jest wykonywany przez powłokę, ale przez truncatektóry jest wykonywany przez sudo przy użyciu uprawnień sudo.

sudo truncate -s 0 filename

Aby uzyskać szczegółowe informacje o programach, które utrzymują otwarty plik, nawet jeśli plik został usunięty, możesz przeczytać:

lesmana
źródło
jest napisane, że Odmowa
dostępu
2
może masz włączoną funkcję noclobber w bash?
lesmana,
Najbardziej kompletna jak dotąd odpowiedź
AbdelHady
4

Aby to zautomatyzować, możesz użyć logrotate. Po prostu stwórz plik konfiguracyjny dla pliku, który chcesz opróżnić, dodaj inne ustawienia i możesz automatycznie go opróżniać codziennie na podstawie kryteriów, które wybierasz na co dzień, lub gdy plik jest większy niż itp.

Zobacz, jak skonfigurować Logrotate: http://linuxcommand.org/man_pages/logrotate8.html

piotrektt
źródło
1
Sam wybieram tę opcję. Używamy „file> 10 Mb” -> „tar.gz it do tworzenia kopii zapasowych” „pustego pliku”. Kopie zapasowe są usuwane po 900 dniach.
Rinzwind
3

echo "" > foo_fileJest to prosty sposób na osiągnięcie tego, zastąpi ona całą zawartość foo_file z „” czyni to w tym przypadku opróżnienia.

Możesz także użyć cat /dev/null > foo_file, który odczyta zerowe urządzenie i nadpisze twój plik niczym.

Bruno Pereira
źródło
jest napisane, że Odmowa zezwolenia, użyłem nazwy pliku chmod 755, ale nadal odmawia zgody
sosytee
Czy potrafisz odczytać uprawnienia do pliku z normalnym użytkownikiem?
Bruno Pereira,
tak, mogę czytać zawartość jak zwykły użytkownik
sosytee