GNU/Linux >> Znalost Linux >  >> Linux

Začínáme s příkazem SED [Příručka pro začátečníky]

Sed je součástí standardní sady nástrojů Unix od konce 60. let. Jako každý textový editor vám pomůže upravit textové soubory. Na rozdíl od textových editorů, které jste již možná použili, se však jedná o neinteraktivní editor.

To znamená, že předem určíte transformace, které chcete použít na soubor, a nástroj pak může tyto transformace použít bez dozoru.

Nejlepší popis cílů návrhu nástroje pochází od Lee E. McMahona, hlavního vývojáře původní implementace ve svém původním dokumentu:

Sed je neinteraktivní kontextový editor, který běží na operačním systému UNIX. Sed je navržen tak, aby byl užitečný zejména ve třech případech:

  1. pro úpravu příliš velkých souborů pro pohodlné interaktivní úpravy;
  2. Upravit soubor libovolné velikosti, když je sekvence editačních příkazů příliš složitá na to, aby se dala pohodlně psát v interaktivním režimu.
  3. Pro efektivní provádění více „globálních“ editačních funkcí v jednom průchodu vstupem.

Návrhy cílů (1) a (3) jsou pravděpodobně méně relevantní pro náš moderní hardware, ale druhý zůstává platný. Jako osobní doplněk bych řekl, že sed je zvláště vhodný pro opakující se úkoly, jako když chcete použít stejnou transformaci na sadu souborů.

Naučte se základní příkazy SED pomocí těchto příkladů

Abychom vám dali ochutnat sílu sed, zvážím případ vývojářky, která potřebuje přidat záhlaví licence nad každý ze zdrojových souborů ve svém projektu:

[email protected]:~$ head MIT.LICENSE *.sh
==> MIT.LICENSE <==
-----8<----------------------------------------------------------------
Copyright <YEAR> <COPYRIGHT HOLDER>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

==> script1.sh <==
#!/bin/bash

echo Hello, I\'m the first script

==> script2.sh <==
#!/bin/bash

cat << EOF
Hello, I'm the second script
EOF

Nejen, že bych chtěl vidět licenční soubor nad každým skriptem shellu, ale také bych chtěl, aby byl rok a zástupný symbol autorských práv nahrazeny jejich skutečnou hodnotou. To bude náš první případ použití.

Poznámka:pokud chcete cvičit sami, můžete si stáhnout ukázkové soubory z mých webových stránek. Můžete se také podívat na video dokončující tento článek:

1. Nahrazení textu v SED

Ve svém licenčním souboru bych chtěl nahradit zástupné symboly a jejich skutečnou hodnotou.

Toto je práce dokonale vhodná pro sed substituci příkaz. Pravděpodobně nejužitečnější ze všech příkazů sed:

[email protected]:~$ sed -e 's/<YEAR>/2018/' MIT.LICENSE  | head -5
-----8<----------------------------------------------------------------
Copyright 2018 <COPYRIGHT HOLDER>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

Pomocí potrubí (| ), předal jsem výstup příkazu sed do head nástroj, který zde zobrazí pouze prvních pět řádků. Nicméně pro naše dnešní specifické téma je nejzajímavější část s/<YEAR>/2018/ výraz.

Sed pracuje tak, že vstupní soubor zpracovává jeden řádek po druhém. Na každém řádku je zástupný znak (s ) příkaz nahradí první výskyt textu mezi prvními dvěma lomítky (/<YEAR>/ ) textem mezi posledními dvěma (/2018/ ). Představte si to jako funkci hledání a nahrazování, kterou máte v textovém editoru GUI.

Zde stojí za zmínku, že původní soubor MIT.LICENSE nebyl upraven. Nechal jsem vás to zkontrolovat sami pomocí následujícího příkazu:

head -5 MIT.LICENSE

2. Nahrazování textu… znovu

Skvělé:nahradili jsme zástupný symbol roku. Ale je tu druhý, který je třeba vyměnit. Pokud jste pochopili předchozí příklad, pravděpodobně si dokážete představit druhý výraz sed, jako je tento:

's/<COPYRIGHT HOLDER>/Sylvain Leroux/'

Ale kam to umístit? No, máte několik možností. Nejzřetelnější, pokud již znáte koncept přesměrování, je přesměrování výstupu našeho prvního příkazu sed do druhé instance sed:

[email protected]:~$ sed -e 's/<YEAR>/2018/' MIT.LICENSE  |
    sed -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' |
    head -5
----8<----------------------------------------------------------------
Copyright 2018 Sylvain Leroux

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

Ale umíme to lépe. Protože -e volba zavádí výraz sed, můžeme jich použít několik jako součást stejného vyvolání sed a výsledek bude stejný:

# Pay special attention to the \ at the end of the lines
# specifying the *same* command continues on the
# next line:
sh$ sed -e 's/<YEAR>/2018/'  \
                -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
                MIT.LICENSE |
        head -5

Nakonec můžete také zadat několik příkazů ve stejném výrazu sed tak, že je oddělíte novým řádkem. To je zvláště užitečné, když začínáte psát složitější programy sed:

# Pay special attention to the single-quotes and
# backslash placement:
sh$ sed -e 's/<YEAR>/2018/
            s/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        MIT.LICENSE |
    head -5

3. Vkládání textu

Nyní jsme nahradili zástupné symboly jejich skutečnou hodnotou. Ale ještě musíme udělat nějakou práci, než budeme moci vložit tento licenční soubor do souborů projektu. Pokud se později jedná o skripty shellu, každý řádek licence musí začínat octothorpem (# ), aby mu shell porozuměl, neměl by se snažit tyto řádky interpretovat.

K tomu opět použijeme příkaz substituce. Něco, co jsem dříve nezmínil, je, na rozdíl od většiny funkcí GUI editorů nahrazujících hledání, vzor hledání není nutně doslovný řetězec, který se má hledat. Ve skutečnosti se jedná o regulární výraz (regulární výraz). To znamená, že kromě prostých znaků, které budou odpovídat doslovně, můžete použít znaky, které budou mít speciální význam. Například stříška (^ ) představuje začátek řádku, znak dolaru ($ ) konec řádku nebo jako poslední příklad tečka-star (.* ) znamená jakoukoli sekvenci 0, 1 nebo několika znaků. Existuje spousta dalších takových metaznaků, ale pro tuto chvíli je to víc než dost.

Tedy k vložení nějaký text na začátku řádku, možností je nahradit začátek řádku tímto textem:

[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^/# /' \
        MIT.LICENSE | head -5
# -----8<----------------------------------------------------------------
# Copyright 2018 Sylvain Leroux
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the

4. Vymazání vybraných řádků

Příkaz substituce v sed je tak univerzální, že pomocí něj můžete vyjádřit většinu textových transformací. Například pro odstranění přerušovaných čar v horní a dolní části textu licence bych mohl napsat toto:

[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^/# /' \
        -e 's/^.*----.*$//' \
        MIT.LICENSE | head -5

# Copyright 2018 Sylvain Leroux
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the

Toto pozdější nahrazení nahradilo prázdným řetězcem veškerý text:

Symbol Popis
^ Začíná na začátku řádku
.* Následuje libovolná sekvence 0, 1 nebo několika znaků
---- Následují 4 pomlčky
.* Následuje libovolná sekvence 0, 1 nebo několika znaků
$ Následuje konec řádku

Ve zkratce se tím nahradí celý řádek prázdným řetězcem if obsahuje čtyři pomlčky za sebou. Samotný prázdný řádek však zůstane ve výstupu a zobrazí se jako prázdný řádek.

V závislosti na vašich přesných potřebách a vkusu můžete také zvážit alternativní řešení níže. Nechal jsem vás to podrobně prozkoumat, abyste mohli určit změny v příkazu a sami identifikovat, jaké to mělo důsledky na výsledek:

[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^.*----.*$//' \
        -e 's/^/# /' \
        MIT.LICENSE | head -5

Pokud se vám zdá regulární výraz použitý k vyčištění řádku příliš složitý, můžeme také využít další funkce sed. Téměř všechny příkazy mohou mít volitelnou adresu před názvem příkazu. Pokud je přítomen, omezí rozsah příkazu na odpovídající řádky ta adresa:

[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^/# /' \
        -e '/----/s/^.*$//' \
        MIT.LICENSE | head -5

Nyní bude nejnovější příkaz náhrady použit pouze na řádky odpovídající (tj. „obsahující“) čtyři pomlčky v řadě. A pro každý odpovídající řádek nahradí vše (.* ) mezi začátkem (^ ) a konec ($ ) řádku prázdným řetězcem (// )

5. Odebírání vybraných řádků

V předchozí části jsme vylepšili příkaz substituce, abychom vymazali některé řádky textu. Ale prázdné řádky zůstaly přítomny. Někdy je to žádoucí. Někdy tomu tak není. V tom druhém případě možná budete chtít prozkoumat smazání příkaz k odstranění celých řádků z výstupu:

# Below, the redirection '> LICENSE' is used to store
# the result of the sed command into the newly
# created LICENSE file:
[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^/# /' \
        -e '/----/d' \
        MIT.LICENSE > LICENSE
[email protected]:~$ head -5 LICENSE
# Copyright 2018 Sylvain Leroux
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including

d je smazat název příkazu. Stejně jako s byla náhrada název příkazu. Zde jsme zadali adresu před příkazem, takže budou odstraněny pouze odpovídající řádky (bez adresy, d příkaz by odstranil každý řádek souboru)

6. Převést na velká

Doposud jsme se zaměřovali převážně na horní část licenčního souboru. Ale skutečně existují některé změny, které bych rád provedl o něco dále v dokumentech. Nejprve se podívejme, o čem mluvím:

[email protected]:~$ sed -ne '/The above/,$p' LICENSE
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# The software is provided "as is", without warranty of any kind,
# express or implied, including but not limited to the warranties of
# merchantability, fitness for a particular purpose and noninfringement.
# In no event shall the authors or copyright holders be liable for any
# claim, damages or other liability, whether in an action of contract,
# tort or otherwise, arising from, out of or in connection with the
# software or the use or other dealings in the software.

Ve výše uvedeném příkazu jsem pomocí volby -n zakázal automatický tisk prostoru vzorů. To znamená, že sed již nebude na výstupu nic tisknout, pokud jej o to výslovně nepožádám. To je přesně to, co dělám pomocí příkazu print (p). Všimněte si, že místo použití jedné adresy před příkazem p jsem použil rozsah pro zobrazení textu mezi řádkem obsahujícím text „The above“ a koncem dokumentu ($).

Příkaz print může být užitečný, když potřebujete extrahovat některé části souboru. Pro dnešek jsem však chtěl pouze zobrazit poslední dva odstavce, abych vysvětlil, co nyní potřebuji:jak je u licenčních souborů tradicí, rád bych se zakryl tím, že je jasné, že software je poskytován „tak, jak je“. Chtěl bych tedy zdůraznit poslední odstavec (začínající „Software“) tím, že jej přepíšu na velká písmena.

V náhradní části substitučního příkazu je znak &nahrazen textem odpovídajícím vyhledávacímu vzoru. Pomocí rozšíření \U GNU můžeme změnit velikost písmen náhradního řetězce:

[email protected]:~$ sed -i -e '/The software/,$s/.*/\U&/' LICENSE
[email protected]:~$ cat LICENSE

Ve formátu prostého textu s/.*/\U&/ znamená „nahradit jakýkoli text (.* )velkými písmeny (\U ) verze sebe sama (& ). Nechal jsem vás, abyste si to sami ověřili, poslední odstavec by měl být nyní psán velkými písmeny. Mimochodem, možná jste si všimli kvůli -i flag, byly změny aplikovány přímo na soubor LICENSE.

To uvidíme podrobněji v další části. Mezitím vás nechám procvičovat a upravovat tyto příkazy podle vaší vůle. Jakmile budete mít licenční soubor, který odpovídá vašemu vkusu, bude čas podívat se, jak jej zahrnout před každý zdrojový soubor projektu.

7. Vložení textového souboru

Pokud zde čekáte nějaký složitý příkaz, budete zklamáni:vložení souboru do jiného je docela jednoduché:

sed -i -e '1r LICENSE' script1.sh
cat script1.sh

Zde je třeba vidět dvě věci:

  1. r LICENSE výraz je příkaz ke čtení a vložit externí soubor do souboru, který se právě zpracovává. Zde má předponu číslo 1 což je adresa odpovídající pouze řádku 1 vstupního souboru.
  2. -i možnost umožňuje změnu souboru na místě . To znamená, že sed vytvoří za scénou dočasný soubor, do kterého uloží svůj výstup, a jakmile bude zpracování dokončeno, nahradí původní soubor upraveným.

Zajímavým vedlejším efektem volby „-i“ je, že můžete na příkazovém řádku zadat několik názvů souborů a sed na každý z nich použije stejné transformace nezávisle :

sed -i -e '1r LICENSE' *.sh

8. Zpět do budoucnosti

Jako náš poslední příklad příkazu sed si představme, že uplynulo několik let a my jsme nyní 1. ledna 2024. Upozornění na autorská práva všech souborů musí být aktualizována. Existuje několik případů použití v závislosti na tom, kdy byly soubory projektu vytvořeny. Naše sdělení o autorských právech by tedy měla mít jeden z těchto dvou formátů:

Aktuální autorská práva Popis
Autorská práva 2023 Pro soubory vytvořené minulý rok
Autorská práva 2018–2023 Pro soubory vytvořené před loňským rokem

Tyto dva případy použití můžeme zachytit najednou pomocí rozšířeného (-E) regulárního výrazu. Jediné „rozšířené“ věci, které zde skutečně použijeme, jsou závorky:

sed -i -Ee 's/Copyright (....)(-....)?/Copyright \1-2024/' *.sh

Doporučuji vám ručně upravit upozornění na autorská práva v souborech *.sh a poté spustit výše uvedený příkaz v různých případech použití, abyste viděli, jak to funguje.

Možná vám to nakonec pomůže pochopit, když ve vyhledávacím vzoru řeknu:Copyright::je doslovný text, který bude odpovídat doslovně; (… .)::definuje snímací skupinu odpovídající čtyřem libovolným znakům. Doufejme, že čtyři číslice roku; (-… .)?::definuje skupinu zachycení odpovídající pomlčce následované čtyřmi libovolnými znaky. Otazník na konci označuje, že skupina je volitelná. Může, ale nemusí být přítomen ve vstupním řádku.

V náhradním řetězci:Copyright::je doslovný text, který bude doslovně zkopírován; \1::je obsah první skupiny zachycení -2024::je doslovný text, který bude doslovně zkopírován.

Pokud jste si udělali čas na kontrolu příkazu sami, mělo by to potvrdit, zda použiji tato pravidla na případy použití popsané v předchozí tabulce, získám něco takového:

Odpovídající text \1 \2 Náhradní řetězec
Autorská práva 2023 2023 Autorská práva 2023–2024
Autorská práva 2018–2023 2018 -2023 Autorská práva 2018–2024

Na závěr našeho průvodce SED

Zde jsme pouze poškrábali povrch. sed nástroj je mnohem výkonnější. I když jsme však viděli pouze čtyři příkazy (s , p , d a i ) a několik základních konstrukcí regulárních výrazů (^ , $ , . , ? a .* ), již máte dostatek znalostí k vyřešení mnoha každodenní problémy.

Protože rád zakončím tutoriál malou výzvou, navrhuji vám toto:pokud jste si stáhli podpůrný materiál, najdete v adresáři projektu soubor s názvem hello.c . Toto je zdrojový soubor základního programu C:

[email protected]:~$ ls
hello.c  MIT.LICENSE  script1.sh  script2.sh
[email protected]:~$ gcc hello.c -o hello
[email protected]:~$ ./hello sylvain
Hello sylvain
[email protected]:~$ cat hello.c

Ve zdrojovém souboru jsou již nějaké komentáře. Pokud je použijete jako příklady syntaxe komentářů v programovacím jazyce C, můžete vložit licenci MIT do hello.c zdrojový soubor pomocí příkazu sed? Můžete použít jeden nebo několik příkazů sed, můžete výstup příkazu sed převést do jiného, ​​můžete použít dočasné soubory, pokud chcete, ale ne povoleno použít jakýkoli jiný příkaz než sed. Zdrojový soubor C by se měl samozřejmě zkompilovat i po vložení licence!

Nechám vás nyní přemýšlet o tomto malém problému a doufám, že se vám tento článek a jeho doprovodné video líbily. Pokud se chcete o sedovi dozvědět více, dejte nám to vědět pomocí sekce komentářů!


Linux
  1. Začínáme se Zsh

  2. Začínáme s ls

  3. Začínáme s PostgreSQL na Linuxu

  1. Začínáme s příkazem tac systému Linux

  2. Začínáme s linuxovým příkazem cat

  3. Začínáme s Multipass – spouštění virtuálních počítačů Ubuntu

  1. Začínáme s GnuCash

  2. Začínáme s Etcher.io

  3. Začínáme s regulárními výrazy