Czy istnieje jakiś krótki sposób na zapisanie wyniku potoku w tym samym pliku, który jest przetwarzany. Na przykład to właśnie robię
$ cat filename | sort | uniq > result
$ rm -f filename
$ mv result filename
Zastanawiałem się, czy można to zrobić w jednym wierszu (nie dodając tych poleceń za pomocą &&)
To nie jest droga, ale znalezienie pomysłu
$ cat filename | sort | uniq > filename
command-line
bash
whitenoisedb
źródło
źródło
echo $(cat filename | sort | uniq > result) > filename
lub coś ? Przechodząc, nie mam czasu, aby tego spróbować.Odpowiedzi:
Możesz użyć
sponge
z pakietu moreutils :Nie potrzebujesz też potoku do
uniq
, ponieważ kiedysort
ma-u
opcję unikatowych linii podczas sortowania.Zauważ, że w systemie GNU z ustawieniami narodowymi UTF-8,
sort -u
lubsort | uniq
nie dawał ci unikalnych linii, ale pierwszy z sekwencji linii, które sortują to samo w bieżącym locale.dałem ci tylko
①
. Zmiana ustawień regionalnych na C wymusza porządek sortowania na podstawie wartości bajtów:źródło
Nie potrzebujesz żadnych dodatkowych poleceń, takich jak
cat
iuniq
bez użyciarm
polecenia imv
polecenia do usunięcia i zmiany nazwy pliku. wystarczy użyć prostej komendy.Jak to działa?
sort
polecenie sortuje nazwę pliku iz-u
opcją usuwa z niego zduplikowane linie. następnie z-o
opcją zapisuje dane wyjściowe do tego samego pliku metodą lokalną.źródło
sort
działania utracisz oryginalny plik.Sugerowany przez Ciebie przykład (poniżej) nie działa, ponieważ faktycznie będziesz jednocześnie czytać i zapisywać do tego samego pliku.
Idea z potokiem lub przekierowaniem polega na tym, że polecenie po lewej i prawej stronie każdej potoku lub przekierowania działa równolegle. Polecenie po prawej przetwarza informacje, które są mu przekazywane z polecenia po lewej stronie, podczas gdy polecenie po lewej stronie jest nadal uruchomione.
Aby scenariusz zadziałał, polecenie, które odczytuje z pliku, musiałoby zakończyć się przed uruchomieniem polecenia zapisującego do pliku. Aby to zadziałało, musisz najpierw przekierować dane wyjściowe do lokalizacji tymczasowej, a następnie, gdy to się skończy, wyślij je z lokalizacji tymczasowej z powrotem do pliku.
Lepszym sposobem na to jest w zasadzie jak w poprzednim przykładzie, w którym przekierowujesz do pliku tymczasowego, a następnie zmieniasz nazwę tego pliku z powrotem na oryginalny (z wyjątkiem tego, że nie musisz najpierw usuwać pliku, ponieważ przeniesienie usuwa dowolny istniejący cel) .
Możesz także zapisać go w zmiennej łańcuchowej, z tą różnicą, że działa tylko wtedy, gdy dane są wystarczająco małe, aby zmieścić się w pamięci jednocześnie.
źródło
cat filename | sort
na justsort filename
-cat
tutaj nie jest to konieczne.cat
w tym przypadku może być niepotrzebne, ale skupiłem się na części przekierowującej.Możesz użyć
tee
polecenia:tee
Komenda czyta ze standardowego wejścia i zapisuje na standardowe wyjście i plików.źródło
(cat ~/file | grep -v 3662 ; printentry 3662) | tee ~/file > /dev/null
działa. Podobnie jak oryginalny post, to nie działa, jeśli tylko> ~/file
beztee
. Tee wydaje się tutaj podobny dosort -o file
, który zapisuje do nazwanego pliku bez kontynuowania tej samej potoku.(cat x | grep -v 7 ; echo 7) | tee x > /dev/null; cat x
Polecam plik tymczasowy i /mv
lub rozwiązanie z linku @ Steven.Możesz używać Vima w trybie Ex:
sort u
sortuj unikalnex
napisz, jeśli zmiany zostały wprowadzone (mają) i wyjdźźródło