Při práci s textovými soubory budete často muset najít a nahradit textové řetězce v jednom nebo více souborech.
sed je s tream ed itor. Může provádět základní manipulaci s textem na souborech a vstupních proudech, jako jsou potrubí. Pomocí sed , můžete vyhledávat, hledat a nahrazovat, vkládat a odstraňovat slova a řádky. Podporuje základní a rozšířené regulární výrazy, které vám umožňují porovnat složité vzory.
V tomto článku si povíme, jak najít a nahradit řetězce pomocí sed . Také vám ukážeme, jak provádět rekurzivní vyhledávání a nahrazování.
Najít a nahradit řetězec řetězcem sed #
Existuje několik verzí sed s některými funkčními rozdíly mezi nimi. macOS používá verzi BSD, zatímco většina distribucí Linuxu přichází s GNU sed ve výchozím nastavení předinstalovaný. Použijeme verzi GNU.
Obecná forma vyhledávání a nahrazování textu pomocí sed má následující tvar:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-i– Ve výchozím nastavenísedzapíše svůj výstup na standardní výstup. Tato možnost říkásedupravovat soubory na místě. Pokud je dodaná přípona (ex -i.bak), vytvoří se záloha původního souboru.s- Náhradní příkaz, pravděpodobně nejpoužívanější příkaz v sed./ / /- Oddělovací znak. Může to být jakýkoli znak, ale obvykle lomítko (/) se používá.SEARCH_REGEX- Normální řetězec nebo regulární výraz k vyhledání.REPLACEMENT- Náhradní řetězec.g- Globální vlajka nahrazení. Ve výchozím nastavenísedpřečte soubor řádek po řádku a změní pouze první výskytSEARCH_REGEXna lince. Když je poskytnut příznak nahrazení, všechny výskyty jsou nahrazeny.INPUTFILE- Název souboru, na kterém chcete spustit příkaz.
Je dobrým zvykem umístit argument do uvozovek, aby se metaznaky shellu nerozšiřovaly.
Podívejme se, jak můžeme použít sed příkaz k vyhledání a nahrazení textu v souborech některými z jeho nejběžněji používaných voleb a příznaků.
Pro demonstrační účely budeme používat následující soubor:
file.txt123 Foo foo foo
foo /bin/bash Ubuntu foobar 456
Pokud g příznak je vynechán, nahradí se pouze první výskyt hledaného řetězce v každém řádku:
sed -i 's/foo/linux/' file.txt 123 Foo linux foo
linux /bin/bash Ubuntu foobar 456
S globálním příznakem nahrazení sed nahradí všechny výskyty vyhledávacího vzoru:
sed -i 's/foo/linux/g' file.txt 123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456
Jak jste si možná všimli, podřetězec foo uvnitř foobar řetězec je také nahrazen v předchozím příkladu. Pokud toto není požadované chování, použijte výraz na hranici slova (\b ) na obou koncích vyhledávacího řetězce. To zajistí, že se dílčí slova nebudou shodovat.
sed -i 's/\bfoo\b/linux/g' file.txt 123 Foo linux linux
linux /bin/bash Ubuntu foobar 456
Chcete-li, aby se ve vzoru nerozlišovala velká a malá písmena, použijte I vlajka. V níže uvedeném příkladu používáme oba g a I příznaky:
sed -i 's/foo/linux/gI' file.txt 123 linux linux linux
linux /bin/bash Ubuntu linuxbar 456
Pokud chcete najít a nahradit řetězec, který obsahuje oddělovací znak (/ ), budete muset použít zpětné lomítko (\ ), abyste unikli lomítku. Například nahradit /bin/bash pomocí /usr/bin/zsh byste použili
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt
Jednodušší a mnohem čitelnější možností je použít jiný oddělovací znak. Většina lidí používá svislou čáru (| ) nebo dvojtečkou (: ), ale můžete použít jakýkoli jiný znak:
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt 123 Foo foo foo
foo /usr/bin/zsh Ubuntu foobar 456
Můžete také použít regulární výrazy. Chcete-li například vyhledat všechna 3místná čísla a nahradit je řetězcem number byste použili:
sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt
number Foo foo foo
foo /bin/bash demo foobar number
Další užitečnou funkcí sed je, že můžete použít znak ampersand & který odpovídá shodnému vzoru. Znak lze použít vícekrát.
Pokud například chcete přidat složené závorky {} kolem každého 3místného čísla zadejte:
sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt
{123} Foo foo foo
foo /bin/bash demo foobar {456}
V neposlední řadě je vždy dobré vytvořit zálohu při úpravě souboru pomocí sed . Chcete-li to provést, stačí zadat příponu záložního souboru do -i volba. Chcete-li například upravit soubor file.txt a uložte původní soubor jako file.txt.bak byste použili:
sed -i.bak 's/foo/linux/g' file.txt
Chcete-li se ujistit, že je záloha vytvořena, uveďte soubory s ls příkaz:
ls file.txt file.txt.bak
Rekurzivní hledání a nahrazení #
Někdy můžete chtít rekurzivně hledat v adresářích soubory obsahující řetězec a nahradit řetězec ve všech souborech. To lze provést pomocí příkazů jako find nebo grep k rekurzivnímu vyhledání souborů v adresáři a převedení názvů souborů do sed .
Následující příkaz rekurzivně vyhledá soubory v aktuálním pracovním adresáři a předá názvy souborů do sed .
find . -type f -exec sed -i 's/foo/bar/g' {} +
Chcete-li se vyhnout problémům se soubory obsahujícími mezeru v názvech, použijte -print0 volba, která říká find vytiskne název souboru následovaný znakem null a výstup převede do sed pomocí xargs -0 :
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
Chcete-li vyloučit adresář, použijte -not -path volba. Pokud například nahrazujete řetězec v místním gitovém repozitáři, abyste vyloučili všechny soubory začínající tečkou (. ), použijte:
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g' Pokud chcete hledat a nahrazovat text pouze v souborech s konkrétní příponou, použijete:
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
Další možností je použít grep příkaz k rekurzivnímu vyhledání všech souborů obsahujících vyhledávací vzor a poté přesměrování názvů souborů do sed :
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g' Závěr č.
I když se to může zdát komplikované a složité, zprvu hledání a nahrazování textu v souborech pomocí sed je velmi jednoduché.
Chcete-li se dozvědět více o sed příkazy, možnosti a příznaky naleznete v příručce sed GNU a výukovém programu sed Grymoire.
Pokud máte nějaké dotazy nebo zpětnou vazbu, neváhejte zanechat komentář.