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,6s
definuje rozsah, od řádku tři dolů po řádek šest./^[^#]/
odpovídá všemu, co je znak a nezačíná křížkem (#
)./# &/g
nahradí čá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.