Próbuję dowiedzieć się, czy można edytować plik za pomocą pojedynczego polecenia sed bez ręcznego przesyłania strumieniowego edytowanej treści do nowego pliku, a następnie zmieniając nazwę nowego pliku na oryginalną nazwę. Wypróbowałem tę -i
opcję, ale mój system Solaris stwierdził, że -i
jest to opcja nielegalna. Czy jest inny sposób?
298
-i
jest opcją w gnu sed, ale nie ma standardowego sed. Jednak przesyła zawartość do nowego pliku, a następnie zmienia nazwę pliku, więc nie jest to, czego chcesz.Odpowiedzi:
-i
opcja strumieni na edytowanej zawartości do nowego pliku, a następnie zmienia nazwę go za kulisami, w każdym razie.Przykład:
i
na macOS .
źródło
sed -i "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>
W systemie, w którym
sed
nie ma możliwości edycji plików, myślę, że lepszym rozwiązaniem byłoby użycieperl
:Chociaż tworzy to plik tymczasowy, zastępuje oryginał, ponieważ dostarczono pusty przyrostek / rozszerzenie.
źródło
sudo
. Moim zdaniem pytanie dotyczy tego, jak uniknąć ręcznego tworzenia i zmiany nazwy pliku tymczasowego bez konieczności instalowania najnowszego GNU lub BSDsed
. Po prostu użyj Perla.sed 's/foo/bar/g' file.txt > file.tmp && mv file.tmp file.txt
. To, że edycja w miejscu zmienia nazwę przy użyciu pliku tymczasowego, nie oznacza, że musi on / ona ręcznie zmienić nazwę, gdy opcja nie jest dostępna. Istnieją inne narzędzia, które mogą robić to, czego chce, a Perl jest oczywistym wyborem. Jak to nie jest odpowiedź na pierwotne pytanie?sed
. Pytanie było rzeczywiście bardzo dobry, ale jego wartość została zmniejszona przez ludzi, którzy albo nie potrafią czytać lub stron podręcznika nie może być jedno, aby rzeczywiście czytają pytania tutaj na SO.Pamiętaj, że w systemie OS X mogą wystąpić dziwne błędy, takie jak „nieprawidłowy kod polecenia” lub inne dziwne błędy podczas uruchamiania tego polecenia. Aby rozwiązać ten problem, spróbuj
To dlatego, że od wersji OSX z
sed
The-i
opcja oczekujeextension
argumentu więc komenda jest analizowany jakoextension
argument i ścieżka do pliku jest interpretowana jako kodu poleceń. Źródło: https://stackoverflow.com/a/19457213źródło
brew install gnu-sed
wraz z aPATH
pozwoli ci korzystać z wersji GNU sed. Dzięki za wzmiankę; zdecydowanie drapak w głowie.Poniższe działa dobrze na moim komputerze Mac
Zastępujemy foo paskiem w przykładowym pliku. Kopia zapasowa oryginalnego pliku zostanie zapisana w sample.bak
Do edycji wbudowanej bez kopii zapasowej użyj następującego polecenia
źródło
Należy zauważyć,
sed
że nie można samodzielnie zapisywać plików, ponieważ jedynym celem sed jest działanie jako edytor w „strumieniu” (tj. Potokach stdin, stdout, stderr i innych>&n
buforach, gniazdach i tym podobnych). Mając to na uwadze, możesz użyć innego polecenia,tee
aby zapisać dane wyjściowe z powrotem do pliku. Inną opcją jest utworzenie łatki z pipingu zawartościdiff
.Metoda tee
Metoda łatki
AKTUALIZACJA:
Zauważ też, że łatka sprawi, że plik zmieni się z pierwszego wiersza wyjścia różnicowego:
Łatka nie musi wiedzieć, do którego pliku uzyskać dostęp, ponieważ znajduje się on w pierwszym wierszu wyniku z diff:
źródło
/dev/stdin 2014-03-15
, odpowiedział 7 stycznia - czy jesteś podróżnikiem w czasie?/dev/stdin
nie istnieje, więc musisz zastąpić/dev/stdin
„-” pojedynczym łącznikiem bez cudzysłowów, więc następujące polecenia powinny działać:$ sed 's/oo/u/' fubar | diff -p fubar -
i$ sed 's/oo/u/' fubar | diff -p fubar - | patch
patch
nie zostanie obcięty. Myślę, że zapisywanie danych wyjściowych w innym pliku, a następniecat
przejście do oryginału byłoby bezpieczniejsze.Nie można robić tego, co chcesz
sed
. Nawet wersjesed
tego typu obsługują-i
opcję edycji pliku w miejscu, robią dokładnie to, czego wyraźnie nie chcesz: zapisują w pliku tymczasowym, a następnie zmieniają jego nazwę. Ale może możesz po prostu użyćed
. Na przykład, aby zmienić wszystkie wystąpieniafoo
nabar
w plikufile.txt
, możesz:Składnia jest podobna do
sed
, ale z pewnością nie dokładnie taka sama.Ale może powinieneś rozważyć, dlaczego nie chcesz używać pliku tymczasowego o zmienionej nazwie. Nawet jeśli nie masz
-i
wsparciased
, możesz łatwo napisać skrypt, który wykona pracę za Ciebie. Zamiast tegosed -i 's/foo/bar/g' file
możesz zrobićinline file sed 's/foo/bar/g'
. Taki skrypt jest trywialny do napisania. Na przykład:powinien być odpowiedni do większości zastosowań.
źródło
inline
i przywołałem, jak opisano powyżej:inline inputfile sed 's/foo/bar/g'
ed
tylko odpowiedź, która naprawdę działa w miejscu. Pierwszy raz, kiedy potrzebujęed
. Dziękuję Ci. Niewielką optymalizacją jest użycieecho -e ",s/foo/bar/g\012 w"
lubecho $',s/foo/bar/g\012 w'
tam, gdzie powłoka pozwala na uniknięcie dodatkowegotr
połączenia.ed
tak naprawdę nie wprowadza modyfikacji na miejscu. Na podstawiestrace
danych wyjściowych GNUed
tworzy plik tymczasowy, zapisuje zmiany w pliku tymczasowym, a następnie przepisuje cały oryginalny plik, zachowując twarde łącza. Ztruss
danych wyjściowych Solaris 11ed
używa również pliku tymczasowego, ale zmienia nazwę pliku tymczasowego na pierwotną nazwę pliku po zapisaniu za pomocąw
polecenia, niszcząc wszelkie twarde łącza.ed
co jest dostarczane z obecnymi makami (Mojave, cokolwiek to oznacza marketingowy żargon), nadal zachowuje twarde linki. YMMVMożesz użyć vi
źródło
sed obsługuje edycję w miejscu. Od
man sed
:Przykład :
Załóżmy, że masz plik
hello.txt
z tekstem:Jeśli chcesz zachować kopię zapasową starego pliku, użyj:
Otrzymasz dwa pliki:
hello.txt
z zawartością:i
hello.txt.bak
ze starą treścią.Jeśli nie chcesz zachować kopii, po prostu nie przekazuj parametru rozszerzenia.
źródło
Nie określiłeś, jakiej powłoki używasz, ale dzięki zsh możesz użyć
=( )
konstrukcji, aby to osiągnąć. Coś w stylu:=( )
jest podobny,>( )
ale tworzy plik tymczasowy, który jest automatycznie usuwany pocp
zakończeniu.źródło
Powinny zachować wszystkie dowiązania twarde, ponieważ dane wyjściowe są kierowane z powrotem w celu zastąpienia zawartości oryginalnego pliku i nie wymagają żadnej specjalnej wersji sed.
źródło
Jeśli zastępujesz tę samą liczbę znaków i po uważnym przeczytaniu edycji „w miejscu” plików ...
Możesz również użyć operatora przekierowania,
<>
aby otworzyć plik do odczytu i zapisu:Zobacz na żywo:
Z podręcznika użytkownika Bash → 3.6.10 Otwieranie deskryptorów plików do odczytu i zapisu :
źródło
Jak powiedział Moneypenny w Skyfall: „Czasami najlepsze są stare sposoby”. Kincade powiedział później coś podobnego.
Udana edycja w miejscu. Dodano „\ nw \ n”, aby zapisać plik. Przepraszamy za opóźnienie w odpowiedzi na prośbę.
źródło
|
. @MattMontag\n
. [range] s / <old> / <new> / <flag> jest formą polecenia zastępczego - paradygmatu wciąż występującego w wielu innych edytorach tekstu (ok, vim, bezpośredni potomek ed) W każdym razieg
flaga oznacza „globalny” i oznacza „Każda instancja w każdej linii, na którą patrzysz”. Zakres3,5
wygląda na liniach 3-5.,5
patrzy na StartOfFile-5,3,
patrzy na linie 3-EndOfFile i,
patrzy na StartOfFile-EndOfFile. Globalne polecenie podstawiania w każdym wierszu, które zastępuje „fałsz” słowem „prawda”. Następniew
wprowadzane jest polecenie zapisu .Bardzo dobre przykłady. Miałem problem z edycją wielu plików, a opcja -i wydaje się być jedynym rozsądnym rozwiązaniem używającym go w poleceniu find. Tutaj skrypt, aby dodać „wersję:” przed pierwszym wierszem każdego pliku:
źródło