Ze względu na nierozpoznany błąd aplikacji mam kilkaset serwerów z pełnym dyskiem. Istnieje jeden plik, który został wypełniony zduplikowanymi wierszami - nie plik dziennika, ale plik środowiska użytkownika ze zmiennymi definicjami (więc nie mogę po prostu usunąć pliku).
Napisałem proste sed
polecenie, aby sprawdzić błędnie dodane wiersze i je usunąć, i przetestowałem je na lokalnej kopii pliku. Działa zgodnie z przeznaczeniem.
Jednak gdy wypróbowałem go na serwerze z pełnym dyskiem, otrzymałem w przybliżeniu następujący błąd (pochodzi z pamięci, nie kopiuj i wklej):
sed: couldn't flush /path/to/file/sed8923ABC: No space left on deviceServerHostname
Oczywiście wiem, że nie ma już miejsca. Dlatego próbuję usunąć rzeczy! ( sed
Polecenie, którego używam, zmniejszy plik linii 4000+ do około 90 linii.)
Moje sed
polecenie jest słusznesed -i '/myregex/d' /path/to/file/filename
Czy istnieje sposób na zastosowanie tego polecenia pomimo pełnego dysku?
(Musi być zautomatyzowany, ponieważ muszę go zastosować na kilkuset serwerach jako szybką poprawkę).
(Oczywiście błąd aplikacji musi zostać zdiagnozowany, ale w międzyczasie serwery nie działają poprawnie ....)
Aktualizacja: Sytuacja, z którą się spotkałem, została rozwiązana poprzez usunięcie czegoś innego, co, jak się okazało, mogę usunąć, ale nadal chciałbym uzyskać odpowiedź na to pytanie, które byłoby pomocne w przyszłości i dla innych osób.
/tmp
jest zakazem; jest w tym samym systemie plików.
Przed zwolnieniem miejsca na dysku przetestowałem i okazało się, że mogę usunąć wiersze vi
, otwierając plik i uruchamiając, :g/myregex/d
a następnie z powodzeniem zapisując zmiany za pomocą :wq
. Wydaje się, że powinno być możliwe zautomatyzowanie tego, bez uciekania się do osobnego systemu plików do przechowywania pliku tymczasowego .... (?)
sed -i
tworzy tymczasową kopię do działania. Podejrzewam, że tak ed
byłoby lepiej, choć nie jestem wystarczająco znajomy, aby zakazać rzeczywistego rozwiązania
ed
uruchomionym: printf %s\\n g/myregex/d w q | ed -s infile
pamiętaj jednak, że niektóre implementacje używają również plików tymczasowych tak jak sed
(możesz spróbować busyboksa ed - afaik nie tworzy pliku tymczasowego)
echo
. użyć printf
. i sed
dodaj znak, który upuścisz w ostatnim wierszu, aby uniknąć utraty spacji końcowych. Ponadto twoja powłoka musi być w stanie obsłużyć cały plik w jednym wierszu poleceń. to twoje ryzyko - najpierw przetestuj. bash
jest w tym szczególnie niedobry (myślę, że ma to do czynienia z miejscem na stosie?) i może cię w każdej chwili zranić. te dwa sed
zalecane przynajmniej wykorzystałyby bufor potoku jądra, aby uzyskać dobry efekt między nimi, ale metoda jest dość podobna. twoje polecenie podrzędne również obetnie, file
czy sed w / in zakończy się powodzeniem.
sed '/regex/!H;$!d;x' <file|{ read v && cat >file;}
i jeśli działa, przeczytaj resztę mojej odpowiedzi.