podczas pracy z plikami tekstowymi często trzeba znaleźć i zastąpić ciągi znaków w jednym lub kilku plikach.
sed
jest edytorem strumieniowym. Może wykonywać podstawową manipulację tekstem na plikach i strumieniach wejściowych, takich jak potoki. Za pomocą sed
możesz wyszukiwać, znajdować i zastępować, wstawiać i usuwać słowa i wiersze. Obsługuje podstawowe i rozszerzone wyrażenia regularne, które pozwalają dopasować złożone wzorce.,
w tym artykule porozmawiamy o tym, jak znaleźć i zastąpić ciągi znaków sed
. Pokażemy również, jak wykonać rekurencyjne wyszukiwanie i zastępowanie.
znajdź i zamień ciąg znaków na sed #
istnieje kilka wersjised
, z pewnymi różnicami funkcjonalnymi między nimi. macOS używa wersji BSD, podczas gdy większość dystrybucji Linuksa jest domyślnie zainstalowana z GNU sed
. Użyjemy wersji GNU.,
ogólna forma wyszukiwania i zastępowania tekstu za pomocą sed
przyjmuje następującą formę:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-
-i
– domyślniesed
zapisuje swoje wyjście na standardowe wyjście. Ta opcja mówised
aby edytować pliki w miejscu. Jeśli podano rozszerzenie (ex-i. bak), zostanie utworzona kopia zapasowa oryginalnego pliku. -
s
– Komenda zastępcza, prawdopodobnie najczęściej używana w sed. -
/ / /
– znak ogranicznika., Może to być dowolny znak, ale zazwyczaj używany jest znak ukośnika (/
). -
SEARCH_REGEX
– zwykły ciąg znaków lub wyrażenie regularne do wyszukiwania. -
REPLACEMENT
– łańcuch zastępczy. -
g
– globalna flaga zastępcza. Domyślniesed
odczytuje wiersz po wierszu pliku i zmienia tylko pierwsze wystąpienieSEARCH_REGEX
w wierszu. Po podaniu flagi zastępczej wszystkie zdarzenia są zastępowane., -
INPUTFILE
– nazwa pliku, na którym chcesz uruchomić polecenie.
dobrą praktyką jest umieszczanie cudzysłowów wokół argumentu, aby meta-znaki powłoki nie były rozszerzane.
zobaczmy, jak możemy użyć poleceniased
do wyszukiwania i zastępowania tekstu w plikach niektórymi z najczęściej używanych opcji i FLAG.
do celów demonstracyjnych użyjemy następującego pliku:
123 Foo foo foo foo /bin/bash Ubuntu foobar 456
jeśli znacznik g
jest pominięty, zastępuje się tylko pierwszą instancję szukanego ciągu w każdej linii:
sed -i 's/foo/linux/' file.txt
123 Foo linux foo linux /bin/bash Ubuntu foobar 456
z globalną flagą zastępczą sed
zastępuje wszystkie wystąpienia wzorca wyszukiwania:
sed -i 's/foo/linux/g' file.txt
123 Foo linux linuxlinux /bin/bash Ubuntu linuxbar 456
jak mogłeś zauważyć, podłańcuch foo
wewnątrz foobar
łańcuch jest również zastąpiony w poprzednim przykładzie., Jeśli nie jest to pożądane zachowanie, użyj wyrażenia granicy słowa (\b
) na obu końcach szukanego ciągu. Zapewnia to, że częściowe słowa nie są dopasowane.
sed -i 's/\bfoo\b/linux/g' file.txt
123 Foo linux linuxlinux /bin/bash Ubuntu foobar 456
aby dopasować wielkość liter do wzorca, Użyj flagiI
., W poniższym przykładzie używamy zarówno g
I I
flagi:
sed -i 's/foo/linux/gI' file.txt
123 linux linux linux linux /bin/bash Ubuntu linuxbar 456
Jeśli chcesz znaleźć i zastąpić łańcuch zawierający znak ogranicznika (/
) musisz użyć ukośnika wstecznego (\
), aby uniknąć ukośnika. Na przykład, aby zastąpić /bin/bash
/usr/bin/zsh
należy użyć
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt
łatwiejszą i dużo bardziej czytelną opcją jest użycie innego znaku ogranicznika., Większość ludzi używa pionowego paska (|
) lub dwukropka (:
), ale możesz użyć dowolnego innego znaku:
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
123 Foo foo foo foo /usr/bin/zsh Ubuntu foobar 456
Możesz również używać wyrażeń regularnych. Na przykład, aby wyszukać wszystkie 3 cyfry i zastąpić je ciągiem number
można użyć:
sed -i 's/\b\{3\}\b/number/g' file.txt
number Foo foo foo foo /bin/bash demo foobar number
Kolejną przydatną funkcją sed jest użycie znaku ampersand &
co odpowiada dopasowanemu wzorcowi., Znak może być używany wielokrotnie.
na przykład, jeśli chcesz dodać klamry {}
wokół każdego 3-cyfrowego numeru, wpisz:
sed -i 's/\b\{3\}\b/{&}/g' file.txt
{123} Foo foo foo foo /bin/bash demo foobar {456}
wreszcie, zawsze dobrym pomysłem jest utworzenie kopii zapasowej podczas edycji pliku z sed
. Aby to zrobić, wystarczy podać rozszerzenie pliku kopii zapasowej do opcji -i
., Na przykład, aby edytować file.txt
I zapisać oryginalny plik jako file.txt.bak
można użyć:
sed -i.bak 's/foo/linux/g' file.txt
aby upewnić się, że kopia zapasowa jest utworzona, lista plików za pomocą ls
polecenie:
ls
file.txt file.txt.bak
rekurencyjnie znajdź i zamień #
czasami możesz chcieć rekurencyjnie przeszukiwać katalogi plików zawierających ciąg znaków i zastępować go we wszystkich plikach., Można to zrobić za pomocą poleceń takich jak find
lub grep
, aby rekurencyjnie znaleźć pliki w katalogu i przekierować nazwy plików do sed
.
następujące polecenie rekurencyjnie wyszukuje pliki w bieżącym katalogu roboczym i przekazuje nazwy plików do sed
.,
find . -type f -exec sed -i 's/foo/bar/g' {} +
aby uniknąć problemów z plikami zawierającymi spację w ich nazwach, użyj opcji -print0
, która informuje find
, aby wydrukować nazwę pliku, a następnie znak null i skierować wyjście do sed
div>używając xargs -0
:
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
aby wykluczyć katalog, użyj opcji -not -path
.,arting z dot (.
), użyj:
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'
Jeśli chcesz wyszukiwać i zastępować tekst tylko na plikach z określonym rozszerzeniem, użyjesz:
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
inną opcją jest użycie grep
polecenie rekurencyjnego znajdowania wszystkich plików zawierających wzorzec wyszukiwania, a następnie przekierowywania nazw plików do sed
:
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'
podsumowanie #
chociaż może to wydawać się skomplikowane i złożone, na początku wyszukiwanie i zastępowanie tekstu w plikach za pomocą sed
jest bardzo prosty.,
aby dowiedzieć się więcej osed
poleceniach, opcjach i flagach, odwiedź podręcznik GNU sed i samouczek Grymoire sed .
Leave a Reply