Jak mogę uzyskać polecenie sed, aby dokonać trwałych zmian w pliku?

32

czy to możliwe? Czytałem gdzieś, że zrobiłoby to następujące polecenie:

sed -e [polecenie] [plik]

ale wydawało się, że robi to samo co sprawiedliwie

sed [polecenie] [plik]

(nie zapisał zmian). Czy można to zrobić za pomocą sed?

Jan
źródło
2
-eFlaga oznacza wyrażenie. Prawdopodobnie chcesz -iflagi, co oznacza in-placei zdecydowanie zalecamy jej użycie sed -i.bak 's/../' filename
Valentin Bajrami

Odpowiedzi:

50

Myślę, że szukasz -i:

   -i[SUFFIX], --in-place[=SUFFIX]

          edit files in place (makes backup if SUFFIX supplied)

Na przykład:

$ cat foo.txt
hello world
$ sed -i 's/o/X/g' foo.txt
$ cat foo.txt
hellX wXrld

Jeśli podasz sufiks, utworzy plik kopii zapasowej:

$ ls
foo.txt
$ sed -i.bak 's/o/X/g' foo.txt 
$ ls
foo.txt  foo.txt.bak

Plik wejściowy jest modyfikowany i tworzona jest kopia zapasowa zawierająca oryginalne dane pliku.

Zauważ też, że dotyczy to GNU sed, istnieją niewielkie różnice w formacie między różnymi sedimplementacjami.

terdon
źródło
4
Zauważ, że strona podręcznika jest niepoprawna. sednie wykonuje edycji na miejscu. Tworzy nowy plik i zastępuje stary, zmienia się i-węzeł.
Marco
2
@Marco To bezpieczny sposób edycji pliku na miejscu. „Edycja pliku na miejscu” w dokumentacji sed oznacza, że ​​oryginalny plik (zgodnie z jego nazwą) jest modyfikowany, a nie, że oryginalny plik (zgodnie z definicją jego i-węzła) jest modyfikowany.
Gilles „SO- przestań być zły”
2
@Gilles Całkowicie się zgadzam, że jest to preferowany sposób edycji pliku, ale raczej nie nazwałbym tego w miejscu . Ale sprowadza się to do pytania, w jaki sposób plik jest identyfikowany, według i-węzła lub nazwy. Powiedziałbym, że przez i-węzeł, w przeciwnym razie konstrukty takie { rm file; cmd > file; } < filedoprowadziłyby do wniosku, że cmd czyta i zapisuje do tego samego pliku, czego nie robi. To dwa odrębne pliki, które akurat mają taką samą nazwę. Ale nie chcę tutaj rozmawiać.
Marco
Na MacOS 10.14 dostaję, sed: 1: "foo.txt": invalid command code fgdy jestem uruchomiony sed -i 's/o/X/g' foo.txt. Jednak zapewnienie rozszerzenia, podobnie jak sed -i .bak 's/o/X/g' foo.txtdziała dobrze. Wszelkie pomysły, jak to zrobić bez tworzenia plików kopii zapasowych?
Joshua Pinter
1
Okej, wymyśliłem to. W systemie macOS należy jawnie dodać pusty ciąg dla opcji parametru rozszerzenia:sed -i '' 's/o/X/g' foo.txt
Joshua Pinter
2

To rozwiązanie działa w przypadku HPUX (UNIX):

1 { rm test1.sh && awk '{gsub("Error", "NO_Error", $0); print}' > test1.sh; } < test1.sh.:

2) perl -pi -e 's/Error/NO_Error/g' test1.sh

3) sed 's/Error/NO_Error/g' test1.sh | tee test1.sh

użytkownik3114790
źródło
Nie możesz użyć koszulki askubuntu.com/a/752451
Steven Penny
1

-eopcja służy do wykonywania wielu sedpoleceń

sed -e 's/linux/unix/' -e 's/os/OS/' file.txt

uznać file.txtza

linux os

wtedy O / P jest

unix os

-i opcja zapisuje zmiany na stałe ...

użytkownik195318
źródło