V předchozím článku jsem se zabýval tím, jak manipulovat s textem pomocí grep . Nyní vraťte svou pozornost k sed (Stream Editor), který se nejlépe hodí pro použití v kanálech (data pocházející z kanálu). sed obslužný program lze použít k vytištění obsahu souboru, nahrazení řádku (nebo více řádků) a následnému uložení souboru. Na rozdíl od grep , sed může nahradit řádek nebo více řádků v souboru a provést na místě aktualizaci tohoto souboru.
Nejjednodušší sed vyvolání při nahrazení foo pro bar je:
$ sed 's/foo/bar/' inputfile Příklad:Odstraňte komentáře
Zatímco grep může formátovat výstup na obrazovce, není schopen upravit soubor na místě. K tomu budete potřebovat souborový editor jako ed . Od ed není součástí tohoto článku, použijte sed abyste dosáhli stejné věci, kterou jste udělali s grep v prvním příkladu předchozího článku. Tentokrát upravte /etc/fstab soubor na místě předávající -i příznak na sed . Bez -i flag , uvidíte pouze to, co by bylo upraveno.
Doporučujeme vám vždy spouštět sed bez -i flag, jen aby se ujistil, že výsledek, který produkuje, je očekáván. sed obslužný program také nabízí -i.bak flag, který před úpravou vytvoří záložní soubor.
Poslední grep příkaz pro tento příklad byl:
$ grep -v '^#' /etc/fstab > ~/fstab_without_comment
S sed , máte:
# sed -i '/^#/d' /etc/fstab
/dev/mapper/VGCRYPTO-ROOT / ext4 defaults,x-systemd.device-timeout=0 1 1
UUID=e9de0f73-ddddd-4d45-a9ba-1ffffa /boot ext4 defaults 1 2
LABEL=SSD_SWAP swap swap defaults 0 0
Příklad:Pouze tisk /etc/passwd uživatelé
V grep například jste vytiskli pouze uživatelská jména z /etc/passwd soubor s následujícím:
$ grep -Eo '^[a-zA-Z_-]+' /etc/passwd
Totéž můžete udělat pomocí sed takto:
$ sed 's/^\([a-zA-Z_-]\+\).*/\1/' /etc/passwd
Ve výše uvedeném příkladu seskupujete shodu podle závorek () a poté vytiskněte odpovídající skupinu pomocí \1 (back-reference), která určuje první skupinu. Pro druhou skupinu byste použili \2 , a tak dále.
Příklad:Nahradit vše foo s bar
V sed , můžete vyhledat vzor a poté nahradit pouze výskyt odpovídající vzoru. Chcete-li nahradit všechny výskyty v souboru inputfile1 od foo na bar globálně, spusťte:
$ sed -i '/foo/bar/g' inputfile1
Příklad:Nahrazení jedné instance
Vezměte soubor inputfile2 , který má následující obsah:
hello world
second line should be replaced
this line should be replaced later
Řekněme, že chcete nahradit should pomocí will , ale pouze pro druhý řádek. Tento příkaz se dělí následovně:
$ sed '/second/s/should/will/' inputfile2
| | | |
| | | with this pattern
| | this pattern
| substitute
Search for the pattern "second"
Tento výstup je odeslán na standardní výstup, nikoli nahrazení obsahu souboru. Výsledek vypadá takto:
$ sed '/second/s/should/will/' inputfile2
hello world
second line will be replaced
this line should be replaced later
sed příkaz rozlišuje velká a malá písmena. Následující nebude fungovat, když se pokusíte nahradit World s there :
$ echo "Hello World" | sed 's/world/there/'
Hello World
GNU sed zavedl nový příznak /I , který ignoruje velikost písmen a bude proveďte výměnu stejným příkazem:
$ echo "Hello World" | sed 's/world/there/I'
Hello there
Příklad:Vytiskněte řadu řádků a ukončete
S sed , můžete také vytisknout řádky a po splnění kritérií skončit. Následující příkazy vytisknou tři řádky a ukončí se. Tento příkaz:
$ sed -n '1,3p' /etc/passwd
je ekvivalentní:
$ sed '3q' /etc/passwd
Následující by bylo nesprávné:
$ sed '1,3q' /etc/passwd # Wrong. You cannot quit three times
Příklad:Zakomentujte nekomentované řádky
Regulární výrazy lze také použít s sed , jak bylo prokázáno dříve. Máte například následující malý skript:
$ cat test_script
#/usr/bin/env bash
this is the first comment
This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Nyní musíte přeskočit první řádek začínající #!/bin/bash a zakomentujte třetí a čtvrtý řádek, ale ne pátý, protože tento řádek je již okomentován.
V sed , můžete použít něco jako:
$ sed '3,6s/^[^#]/# &/g' test_script
#/usr/bin/env bash
# this is the first comment
# This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Ve výše uvedeném příkazu se provede následující:
3,6sdefinuje rozsah, od řádku tři dolů po řádek šest./^[^#]/odpovídá všemu, co je znak a nezačíná křížkem (#)./# &/gnahradí část, v tomto případě vloží#před řádek diktovaný&podepsat.
Příklad:Odebrat všechny číslice
Různé aplikace generují data v různých formátech. Pomocí sed , můžete si ponechat pouze data, která můžete použít. Máte například následující soubor (inputfile3 ) v tomto formátu:
foo1234
bar99128
baz2842
qux12953
discard39120
Možná program vygeneroval špatný formát nebo zřetězil pole do jednoho. Co kdyby vás zajímalo pouze zachování alfa znaků a chtěli byste zahodit číslice? Jak byste tohoto cíle dosáhli pomocí sed ?
Odpověď je pravděpodobně jednodušší, než si myslíte:
$ sed 's/\([a-z]*\).*/\1/' inputfile3
foo
bar
baz
qux
discard
Příklad:Změna konkrétních řádků
Dále sed může také zpracovávat rozsahy podle vzoru, což znamená, že můžete zadat start a konec řetězec a manipulovat s rozsahem. Například:
$ cat inputfile4
hello world
start of the comment
another comment
end of a comment
dont comment this line
nor this line
Následující sed příkaz bude komentovat řádky začínající start a končící na end :
$ sed '/start/,/end/ s/^/# /' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
Zbavte se také prázdných řádků.
$ sed '/start/,/end/ s/^/# /;/^$/d' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
sed toho obsahuje mnohem více a jeho bohaté funkce. Aby bylo možné plně využít sed schopnosti, podívejte se prosím na stránku s dokumentací, kterou najdete zde. Také skvělý zdroj informací o sed naleznete zde.
Shrnutí
Jak jsem uvedl dříve, použijete grep když chcete hledat vzor, buď v souboru nebo ve více adresářích rekurzivně. Použijte sed pokud přijímáte data z potrubí nebo chcete s daty za běhu manipulovat.
sed příkaz je napsaný a je snadné se naučit provádět základní operace. Vše, co potřebujete, je praxe, zejména s regulárními výrazy.