Mam plik temp.txt, który chcę posortować za pomocą sort
polecenia w bash.
Chcę, aby posortowane wyniki zastąpiły oryginalny plik.
Na przykład to nie działa (otrzymuję pusty plik):
sortx temp.txt > temp.txt
Czy można to zrobić w jednej linii bez konieczności kopiowania do plików tymczasowych?
EDYCJA: Ta -o
opcja jest bardzo fajna sort
. Użyłem sort
w moim pytaniu przykładu. Mam ten sam problem z innymi poleceniami:
uniq temp.txt > temp.txt.
Czy istnieje lepsze rozwiązanie ogólne?
Odpowiedzi:
źródło
sort --inplace *.txt
? To byłoby szalenie fajnefind . -name \*.txt -exec sort {} -o {} \;
A
sort
musi zobaczyć wszystkie dane wejściowe, zanim będzie można rozpocząć wyprowadzanie. Z tego powodusort
program może łatwo oferować opcję modyfikacji pliku w miejscu:W szczególności dokumentacja GNU
sort
mówi:Podczas gdy dokumentacja BSD
sort
mówi:Polecenia, takie jak
uniq
mogą rozpocząć zapisywanie danych wyjściowych, zanim zakończą odczytywanie danych wejściowych. Te polecenia zazwyczaj nie obsługują edycji lokalnej (i byłoby im trudniej obsługiwać tę funkcję).Zwykle omijasz ten problem z plikiem tymczasowym lub jeśli absolutnie chcesz uniknąć posiadania pliku pośredniego, możesz użyć bufora do przechowywania pełnego wyniku przed jego wypisaniem. Na przykład z
perl
:Tutaj część perla odczytuje pełne dane wyjściowe ze
uniq
zmiennej,$_
a następnie zastępuje oryginalny plik tymi danymi. Możesz zrobić to samo w wybranym języku skryptowym, być może nawet w Bash. Pamiętaj jednak, że będzie potrzebować wystarczającej ilości pamięci do przechowywania całego pliku, nie jest to zalecane podczas pracy z dużymi plikami.źródło
Oto bardziej ogólne podejście, działa z uniq, sort i innymi.
źródło
sponge
z moreutils:cat file |frobnicate |sponge file
.Komentarz Tobu na temat gąbki gwarantuje, że jest odpowiedzią samą w sobie.
Cytat ze strony głównej moreutils :
Jednak
sponge
cierpi na ten sam problem, o którym mówi tutaj Steve Jessop. Jeśli którekolwiek z poleceń w potokusponge
nie powiedzie się, oryginalny plik zostanie nadpisany.Ups,
my-important-file
odszedł.źródło
set -o pipefail
na początku swojego skryptu, błąd namistyped_command my-important-file
spowodowałby natychmiastowe zakończenie skryptu, przed wykonaniemsponge
, zachowując w ten sposób ważny plik.Proszę bardzo, jedna linia:
Z technicznego punktu widzenia nie ma kopiowania do pliku tymczasowego, a polecenie „mv” powinno być natychmiastowe.
źródło
Podoba mi się
sort file -o file
odpowiedź, ale nie chcę dwukrotnie wpisywać tej samej nazwy pliku.Korzystanie z rozszerzenia historii BASH :
po naciśnięciu przechwytuje pierwszy argument bieżącego wiersza enter.
Unikalne sortowanie na miejscu:
przechwytuje ostatni argument w bieżącej linii.
źródło
Wielu wspominało o opcji -o . Oto część strony podręcznika.
Ze strony podręcznika:
źródło
Byłoby to mocno ograniczone do pamięci, ale można by użyć awk do przechowywania danych pośrednich w pamięci, a następnie zapisać je z powrotem.
źródło
>
obcięcie pliku przeduniq
odczytaniem go przez polecenie ( w tym przypadku).Alternatywa dla
sponge
bardziej powszechnychsed
:Działa na każdej komendzie (
sort
,uniq
,tac
, ...) i wykorzystuje bardzo dobrze znanysed
jest-i
opcja (edytowanie plików w miejscu).Ostrzeżenie: spróbuj
command file
najpierw, ponieważ edycja plików na miejscu nie jest z natury bezpieczna.Wyjaśnienie
Po pierwsze, mówisz
sed
nie do wydrukowania (oryginalna) linii (-n
opcja ), a także z pomocąsed
„sr
dowodzenia ibash
” s Zmiana procesu , generowany przez treść<(command file)
będzie wyjście zapisywane w miejscu .Jeszcze łatwiejsze
Możesz opakować to rozwiązanie w funkcję:
Przykład
źródło
Użyj argumentu
--output=
lub-o
Właśnie wypróbowałem na FreeBSD:
źródło
Aby dodać tę
uniq
możliwość, jakie są wady:źródło
Przeczytać na nieinterakcyjnym edytorze
ex
.źródło
Jeśli nalegasz na użycie
sort
programu, musisz użyć pliku pośredniego - nie sądzę, abysort
miał opcję sortowania w pamięci. Każda inna sztuczka ze stdin / stdout nie powiedzie się, chyba że możesz zagwarantować, że rozmiar bufora dla standardowego wejścia sortowania jest wystarczająco duży, aby zmieścić się w całym pliku.Edycja: wstyd mi.
sort temp.txt -o temp.txt
działa doskonale.źródło
Inne rozwiązanie:
źródło
<>
sztuczka działa tylko w tym przypadku, ponieważuniq
jest wyjątkowa, ponieważ kopiuje tylko linie wejściowe do linii wyjściowych, pomijając niektóre po drodze. Jeślised
użyto innego polecenia (np. ), Które zmieniłoby wejście (np. Zmieniłoby każdea
naaa
), to może ono nadpisaćfile
w sposób, który nie ma żadnego sensu, a nawet zapętlić się w nieskończoność, pod warunkiem, że wejście jest wystarczająco duże (więcej niż pojedynczy bufor odczytu).