GNU/Linux >> Znalost Linux >  >> Linux

Začínáme s regulárními výrazy:Příklad

V části Představení regulárních výrazů , Popsal jsem, co jsou a proč jsou užitečné. Nyní potřebujeme příklad ze skutečného světa, který použijeme jako učební nástroj. Zde je jeden, se kterým jsem se setkal před několika lety.

Tento příklad zdůrazňuje sílu a flexibilitu příkazového řádku Linuxu, zejména regulárních výrazů, pro jejich schopnost automatizovat běžné úlohy. Během své kariéry jsem spravoval několik listservů a stále to dělám. Lidé mi posílají e-mailové adresy, abych je přidal do těchto seznamů. Ve více než jednom případě jsem obdržel seznam jmen a e-mailových adres ve formátu Microsoft Word, které mají být přidány do jednoho ze seznamů.

Obtížný seznam

Samotný seznam nebyl příliš dlouhý, ale jeho formátování bylo nejednotné. Zkrácená verze tohoto seznamu se změnami názvu a domény je uvedena zde:

Team 1	Apr 3 
Leader  Virginia Jones  [email protected]	
Frank Brown  [email protected]	
Cindy Williams  [email protected]	
Marge smith   [email protected] 
 [Fred Mack]   [email protected]	

Team 2	March 14
leader  Alice Wonder  [email protected]	
John broth  [email protected]	
Ray Clarkson  [email protected]	
Kim West    [email protected]	
[JoAnne Blank]  [email protected]	

Team 3	Apr 1 
Leader  Steve Jones  [email protected]	
Bullwinkle Moose [email protected]	
Rocket Squirrel [email protected]	
Julie Lisbon  [email protected]	
[Mary Lastware) [email protected]

Původní seznam obsahoval řádky navíc, znaky jako závorky a závorky, které je třeba odstranit, mezery, jako jsou mezery a tabulátory, a některé prázdné řádky. Formát požadovaný pro přidání těchto e-mailů do seznamu je <first> <last> <[email protected]> . Naším úkolem je převést tento seznam do formátu použitelného softwarem konference.

Bylo zřejmé, že potřebuji manipulovat s daty, abych je zpracoval do přijatelného formátu pro vstup do seznamu. K provedení nezbytných změn v tomto malém souboru je možné použít textový editor nebo textový procesor, jako je LibreOffice Writer. Lidé mi však takové soubory posílají poměrně často, takže je pro mě oříšek použít textový procesor k provedení těchto změn. Navzdory skutečnosti, že Writer má dobrou funkci vyhledávání a nahrazování, každý znak nebo řetězec musí být nahrazen samostatně a neexistuje způsob, jak uložit předchozí hledání.

Writer má výkonnou funkci maker, ale neznám ani jeden z jeho dvou jazyků:LibreOffice Basic nebo Python. Znám programování shellu Bash.

Udělal jsem to, co je pro systémového správce přirozené – zautomatizoval jsem úkol. První věc, kterou jsem udělal, bylo zkopírovat data adresy do textového souboru, abych na nich mohl pracovat pomocí nástrojů příkazového řádku. Po několika minutách práce jsem vyvinul program příkazového řádku Bash uvedený v předchozím článku:

$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/\]//g" -e "s/)//g" | awk '{print $1" "$2" <"$3">"}' > addresses.txt

Tento kód vytvořil požadovaný výstup jako soubor addresses.txt . Použil jsem svůj normální přístup k psaní programů příkazového řádku, jako je tento, vytvářením kanálu po jednom příkazu.

Rozdělme toto potrubí na jeho jednotlivé části, abychom viděli, jak funguje a jak do sebe zapadá. Všechny experimenty v této sérii by měly být prováděny jako neprivilegovaný uživatel. Udělal jsem to také na virtuálním počítači, který jsem vytvořil pro testování:studentvm1 .

Ukázkový soubor

Nejprve musíme vytvořit ukázkový soubor. Vytvořte adresář s názvem testing na místním počítači a poté zkopírujte níže uvedený text do nového textového souboru s názvem Experiment_6-1.txt , který obsahuje tři týmové záznamy zobrazené výše.

Team 1  Apr 3 
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  

Team 2  March 14
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]

Team 3  Apr 1 
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]

Odstranění nepotřebných řádků pomocí grep

První věci, které vidím, že lze udělat, je několik snadných. Vzhledem k tomu, že názvy a data týmů jsou na řádcích samy o sobě, můžeme použít následující k odstranění těch řádků, které mají slovo "Tým:"

[student@studentvm1 testing]$  cat Experiment_6-1.txt | grep -v Team

Nebudu reprodukovat výsledky každé fáze budování tohoto programu Bash, ale měli byste být schopni vidět změny v datovém toku, jak se zobrazují na STDOUT, terminálové relaci. Neuložíme to do souboru až do konce.

V tomto prvním kroku při transformaci datového toku na použitelný datový tok použijeme grep příkaz s jednoduchým doslovným vzorem Team . Literály jsou nejzákladnějším typem vzoru, který můžeme použít jako regulární výraz, protože v prohledávaném datovém toku existuje pouze jedna možná shoda, a to řetězec Team .

Potřebujeme zahodit prázdné řádky, abychom mohli použít jiný grep prohlášení k jejich odstranění. Zjistil jsem, že uzavření regulárního výrazu pro druhý grep příkaz v uvozovkách zajišťuje, že bude správně interpretován:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]
[Mary Lastware) [email protected]
[student@studentvm1 testing]$

Výraz "^\s*$" ilustruje kotvy a používá zpětné lomítko (\) jako escape znak změnit význam doslovného "s" (v tomto případě) na metaznak, který znamená jakékoli mezery, jako jsou mezery, tabulátory nebo jiné znaky, které nelze vytisknout. Tyto znaky v souboru nevidíme, ale některé z nich obsahuje.

Hvězdička alias ikona (*) určuje, že máme odpovídat nule nebo více bílým znakům. Toto přidání by odpovídalo více tabulátorům, více mezerám nebo jakékoli jejich kombinaci v jinak prázdném řádku.

Zobrazení dalších mezer pomocí Vim

Dále jsem nakonfiguroval svůj editor Vim tak, aby zobrazoval mezery pomocí viditelných znaků. Udělejte to přidáním následujícího řádku do svého vlastního ~.vimrc nebo do globálního /etc/vimrc konfigurační soubor:

set listchars=eol:$,nbsp:_,tab:<->,trail:~,extends:>,space:+

Poté spusťte – nebo restartujte – Vim.

Při hledání toho, jak to udělat, jsem na internetu našel spoustu špatných, neúplných a protichůdných informací. Vestavěná nápověda Vim má nejlepší informace a datová linka, kterou jsem vytvořil z výše uvedeného, ​​je ta, která mi vyhovuje.

Poznámka: V níže uvedeném příkladu jsou běžné mezery zobrazeny jako +; karty jsou zobrazeny jako < , <> nebo <–> a vyplňte délku prostoru, který štítek pokrývá. Znak konce řádku (EOL) je zobrazen jako $ .

Výsledek před jakoukoli operací se souborem je zobrazen zde:

Team+1<>Apr+3~$
[email protected]<-->$
[email protected]<---->$
[email protected]<--->$
[email protected]~$
+[Fred+Mack][email protected]<>$
$
Team+2<>March+14$
[email protected]<----->$
[email protected]<>$
[email protected]<-->$
[email protected]>$
[JoAnne+Blank][email protected]<---->$
$
Team+3<>Apr+1~$
[email protected]<-->$
[email protected]<--->$
[email protected]<>$
[email protected]<------>$
[Mary+Lastware)[email protected]$

Odstranění nepotřebných znaků pomocí sed

Můžete vidět, že existuje mnoho mezer, které je třeba z našeho souboru odstranit. Musíme se také zbavit slova „vůdce“, které se objevuje dvakrát a jednou je velké. Nejprve se zbavme „vůdce“. Tentokrát použijeme sed (editor streamu) k provedení tohoto úkolu nahrazením vzoru, kterému odpovídá, novým řetězcem – nebo v našem případě nulovým řetězcem.

Přidání sed -e "s/[Ll]eader//" do potrubí dělá toto:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//"

V tomto sed příkaz -e znamená, že výraz v uvozovkách je skript, který vytváří požadovaný výsledek. Ve výrazu s znamená, že se jedná o substituci. Základní forma substituce je s/<regex>/<replacement string>/ , tedy /[Ll]eader/ je náš vyhledávací řetězec.

Sada [Ll] odpovídá L nebo l , tedy [Ll]eader odpovídá leader nebo Leader . V tomto případě je nahrazující řetězec null, protože vypadá jako dvojité lomítko bez znaků nebo mezer mezi dvěma lomítky (// ).

Zbavme se také některých nadbytečných znaků, jako je []() to nebude potřeba:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g"

Do sed jsme přidali čtyři nové výrazy prohlášení. Každý odebere jeden znak. První z těchto dalších výrazů je trochu jiný, protože levá hranatá závorka ([ ) znak může označovat začátek sady. Musíme opustit složenou závorku, abychom zajistili, že sed interpretuje jej správně jako běžný znak a ne jako speciální.

Uklidit pomocí awk

Mohli bychom použít sed odstranit úvodní mezery z některých řádků, ale awk to dokáže, v případě potřeby změňte pořadí polí a přidejte <> znaky kolem e-mailové adresy:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'

awk utility je ve skutečnosti výkonný programovací jazyk, který dokáže přijímat datové toky na svém STDIN. Tato skutečnost jej činí extrémně užitečným v programech a skriptech příkazového řádku.

awk obslužný program pracuje s datovými poli a výchozím oddělovačem polí jsou mezery – libovolné množství prázdného místa. Datový tok, který jsme dosud vytvořili, má tři pole oddělená mezerami (<first> , <last> a <email> ):

awk '{print $1" "$2" <"$3">"}'

Tento malý program zabírá každé ze tří polí ($1 , $2 a $3 ) a extrahuje je bez úvodních nebo koncových mezer. Poté je vytiskne postupně, přičemž mezi každý přidá jednu mezeru a také <> znaků potřebných k uzavření e-mailové adresy.

Zabalení

Posledním krokem by bylo přesměrování výstupního datového toku do souboru, ale to je triviální, takže provedení tohoto kroku nechávám na vás. Ve skutečnosti to není nutné.

Uložil jsem program Bash do spustitelného souboru a nyní mohu spustit tento program, kdykoli obdržím nový seznam. Některé z těchto seznamů jsou poměrně krátké, jako je ten v tomto příkladu. Jiné byly poměrně dlouhé, někdy obsahovaly až několik stovek adres a mnoho řádků „věcí“, které neobsahovaly adresy, které mají být přidány do seznamu.

Poznámka: Tento článek je mírně upravenou verzí kapitoly 6 z druhého dílu mé knihy o Linuxu, Používání a správa Linuxu:Zero to SysAdmin, která má vyjít na Apress koncem roku 2019.


Linux
  1. Začínáme se Zsh

  2. Začínáme se Sambou pro interoperabilitu

  3. Jak na to:Začínáme s Ansible

  1. Začínáme s ls

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

  3. Začínáme s SSH v Linuxu

  1. Začínáme s GnuCash

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

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