------------------------------------------------------------------------- UZITEČNÉ JEDNOŘÁDKOVÉ SKRIPTY PRO SED (Unixový stream editor) 29.12.2005 Sestavil Eric Pement - pemente[at]northpark[dot]edu verze 5.5 Přeložil Josef Moudřík - j.moudrik[at]seznam[dot]cz Nejnovější verze tohoto souboru (v Angličtině) je obvykle na: http://underpop.online.fr/s/sed/sed1line.txt http://www.pement.org/sed/sed1line.txt Tento soubor je také dostupný v ostatních jazycích: Čínsky - http://underpop.online.fr/s/sed/sed1line_zh-cn.html Czechsky - http://underpop.online.fr/s/sed/sed1line_cz.html Holandsky - http://underpop.online.fr/s/sed/sed1line_nl.html Francouzsky - http://underpop.online.fr/s/sed/sed1line_fr.html Německy - http://underpop.online.fr/s/sed/sed1line_de.html Portugalsky - http://underpop.online.fr/s/sed/sed1line_pt-br.html MEZERY V SOUBORU: # za každý řádek přidá volný řádek sed G # za každý řádek přidá volný řádek a navíc zajistí, že nikde # nebudou dva volné řádky za sebou sed '/^$/d;G' # za každý řádek přidá dva volné řádky sed 'G;G' # odstraní každý druhý řádek sed 'n;d' # vloží prázdný řádek před každý řádek, který obsahuje "regex" sed '/regex/{x;p;x;}' # vloží prázdný řádek za každý řádek, který obsahuje "regex" sed '/regex/G' # vloží prázdný řádek před i za každý řádek, který obsahuje "regex" sed '/regex/{x;p;x;G;}' ČISLOVÁNÍ: # očísluje všechny řádky v souboru (zarovnání vlevo). Použití tabulátorů # (viz. poznámka o \t níže) zajistí odsazení. sed = filename | sed 'N;s/\n/\t/' # očísluje řádky v souboru (čísla vlevo, zarovnání vpravo) sed = filename | sed 'N; s/^/ /; s/ *\(.\{6,\}\)\n/\1 /' # očísluje řádky v souboru jen pokud řádek není prázdný sed '/./=' filename | sed '/./N; s/\n/ /' # spočte řádky (namísto "wc -l") sed -n '$=' PŘEVODY TEXTU A NAHRAZOVÁNÍ: # V UNIXu: převede DOSové nové řádky (CR/LF) na Unixový formát. sed 's/.$//' # předpokladá že řádky konči CR/LF sed 's/^M$//' # v bash a v tcsh stiskni Ctrl-V, poté Ctrl-M sed 's/\x0D$//' # pracuje s ssed, gsed 3.02.80 a vyšší # V UNIXu: převede Unixové nové řádky (LF) na DOSový formát. sed "s/$/`echo -e \\\r`/" # příkazová řádka v ksh sed 's/$'"/`echo \\\r`/" # příkazová řádka v bash sed "s/$/`echo \\\r`/" # příkazová řádka v zsh sed 's/$/\r/' # gsed 3.02.80 a vyšší # V DOSu: převede Unixové nové řádky (LF) na DOSový formát. sed "s/$//" # 1. způsob sed -n p # 2. způsob # V DOSu: převede DOSové konce řádek (CR/LF) na Unixový formát. # Funguje pouze s editorem sed z UnxUtils, verze 4.0.7 a vyšší. Verze # UnxUtils lze zjistit přepínačem "--text", viz. tez přepínač "--help". # Jinak převod DOSového nového řádku na Unix pomocí sedu nejde. Užijte "tr". sed "s/\r//" infile >outfile # UnxUtils sed verze 4.0.7 ci vyšší tr -d \r < infile >outfile # GNU tr verze 1.22 nebo vyšší # smaže prázdné místo (mezery, tabulátory) na začátku každé řádky # zarovná celý text vlevo sed 's/^[ \t]*//' # viz. poznámka '\t' níže # smaže prázdné místo (mezery, tabulátory) na konci řádky sed 's/[ \t]*$//' # viz. poznámka '\t' níže # smaže prázdné místo (mezery, tabulátory) ze začátku i z konce sed 's/^[ \t]*//;s/[ \t]*$//' # vloží 5 mezer na začátek každé řádky sed 's/^/ /' # zarovná celý text vpravo, na celkovou šířku 79 znaků ve sloupci sed -e :a -e 's/^.\{1,78\}$/ &/;ta' # zarovná na 78 znaků + 1 mezera # vycentruje celý text do středu 79 znakového sloupce. První způsob # počítá mezery na začátku a na konci jako normální znak, druhým # jsou mezery na začátku odstraněny. sed -e :a -e 's/^.\{1,77\}$/ & /;ta' # 1. způsob sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/' # 2. způsob # prohodí (najde a nahradí) "foo" a "bar" na každé řádce sed 's/foo/bar/' # nahradí jen první výskyt na řádce sed 's/foo/bar/4' # nahradí jen čtvrtý výskyt na řádce sed 's/foo/bar/g' # nahradí všechny výskyty na řádce sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # nahradí předposlední výskyt sed 's/\(.*\)foo/\1bar/' # nahradí poslední výskyt # nahradí "foo" výrazem "bar" JEN na řádkách, které obsahují "baz" sed '/baz/s/foo/bar/g' # nahradí "foo" vy$razem "bar" JEN na řádkách, které neobsahují "baz" sed '/baz/!s/foo/bar/g' # nahradí "scarlet", nebo "ruby", nebo "puce" výrazem "red" sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' # větsina sedů gsed 's/scarlet\|ruby\|puce/red/g' # pouze GNU sed # vypíše soubor od konce (namísto "tac") # chyba (vlastnost) v editoru HHsed verze 1.5 smaže prázdné řádky sed '1!G;h;$!d' # 1. způsob sed -n '1!G;h;$p' # 2. způsob # vypíše řádky od konce (namísto "rev") sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//' # spojí každé dvě řádky (jako "paste") sed '$!N;s/\n/ /' # pokud řádka končí zpětným lomítkem připojí následující řádku sed -e :a -e '/\\$/N; s/\\\n//; ta' # pokud řádka začíná rovnítkem připojí ji k předchozí řádce # a nahradí "=" mezerou sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D' # přidá čárky k číslům - změní "1234567" na "1,234,567" gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta' # GNU sed sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' # ostatní sedy # přidá mezery k čislům - změní "1234567" na "1 234 567" gsed ':a;s/\B[0-9]\{3\}\>/ &/;ta' # GNU sed sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1 \2/;ta' # ostatní sedy # přidá čárku k čislům s desetinnou čárkou a znaménkem mínus (GNU sed) gsed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta' # přidá prázdnou řádku po každé páté řádce (po 5, 10, atd.) gsed '0~5G' # pouze GNU sed sed 'n;n;n;n;G;' # ostatní sedy VYPSÁNÍ URČITÝCH ŘÁDEK: # vypíše prvních 10 řádek v souboru (namísto "head -n 10") sed 10q # vypíše první řádku souboru (namísto "head -n 1" sed q # vypíše posledních 10 řádek v souboru (namísto "tail") sed -e :a -e '$q;N;11,$D;ba' # vypíše poslední 2 řádky souboru (namísto "tail -n 2") sed '$!N;$!D' # vypíše poslední řádku souboru (namísto "tail -n 1") sed '$!d' # 1. způsob sed -n '$p' # 2. způsob # vypíše předposlední řádku v souboru sed -e '$!{h;d;}' -e x # pro 1-řádkový soubor vypíše prázdnou řádku sed -e '1{$q;}' -e '$!{h;d;}' -e x # pro 1-řádkový soubor vypíše řádku sed -e '1{$d;}' -e '$!{h;d;}' -e x # pro 1-řádkový soubor nevypíše nic # vypíše pouze řádky, které obsahují "regexp" (namísto "grep") sed -n '/regexp/p' # 1. způsob sed '/regexp/!d' # 2. způsob # vypíše pouze řádky, které NEobsahují "regexp" (namísto "grep -v") sed -n '/regexp/!p' # 1. způsob, viz. zadání sed '/regexp/d' # 2. způsob, kratší kod # vytiskne řádku před tou, která obsahuje "regexp" sed -n '/regexp/{g;1!p;};h' # vytiskne řádku po té, co obsahuje "regexp" sed -n '/regexp/{n;p;}' # vytiskne číslo řádky obsahující "regexp", řádku před ní, jí samotnou # a řádku po ní (podobně "grep -A1 -B1") sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h # grep pro AAA, BBB a CCC (v libovolném pořadí) sed '/AAA/!d; /BBB/!d; /CCC/!d' # grep pro AAA, BBB a CCC (v tomto pořadí) sed '/AAA.*BBB.*CCC/!d' # grep pro AAA, nebo BBB, nebo CCC (namísto "egrep") sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # větsina sedů gsed '/AAA\|BBB\|CCC/!d' # pouze GNU sed # vypíše odstavec obsahující AAA (odstavce jsou odděleny prázdnými řádkami) # HHsed verze 1.5 musí mit 'G;' po 'x;' v následujících třech skriptech sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;' # vypíše odstavec obsahující AAA, BBB a CCC (v libovolném pořadí) sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d' # vypíše odstavec obsahující AAA, nebo BBB, nebo CCC sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d' # pouze GNU sed # vypíše jen řádky s 65 znaky, nebo víc sed -n '/^.\{65\}/p' # vypíše jen řádky s méně než 65 znaky sed -n '/^.\{65\}/!p' # 1. způsob, viz. zadání sed '/^.\{65\}/d' # 2. způsob, kratší zápis # vypíše soubor od "regexp" do konce sed -n '/regexp/,$p' # vypíše část souboru dle čísla řádek (řádky 8-12, včetně) sed -n '8,12p' # 1. způsob sed '8,12!d' # 2. způsob # vypíše řádku číslo 52 sed -n '52p' # 1. způsob sed '52!d' # 2. způsob sed '52q;d' # 3. způsob, rychlé i na velkých souborech # počínaje 3-tí, vypíše každou sedmou řádku gsed -n '3~7p' # pouze GNU sed sed -n '3,${p;n;n;n;n;n;n;}' # ostatní sedy # vypíše část souboru mezi dvěma výrazy (včetně) sed -n '/Iowa/,/Montana/p' # pozor na VELKÁ a malá písmena MAZÁNÍ VYBRANÝCH ŘÁDEK: # vypíše vše AŽ na oblast mezi "Iowa" a "Montana" sed '/Iowa/,/Montana/d' # smaže duplicitní, po sobě jdoucí řádky ze souboru (namísto "uniq"). # První řádka v řade duplicitních zůstane, ostatní jsou smazány. sed '$!N; /^\(.*\)\n\1$/!P; D' # smaže duplicitní řádky nejdoucí po sobě. Pozor na přetečení bufferu, # jinak užijte GNU sed. sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P' # smaže všechny řádky výskytující se jednou (namísto "uniq -d") # (soubor musí být seřazen) sed '$!N; s/^\(.*\)\n\1$/\1/; t; D' # smaže prvních 10 řádek v souboru sed '1,10d' # smaže poslední řádku sed '$d' # smaže poslední dvě řádky sed 'N;$!P;$!D;$d' # smaže posledních deset řádek sed -e :a -e '$d;N;2,10ba' -e 'P;D' # 1. způsob sed -n -e :a -e '1,10!{P;N;D;};N;ba' # 2. způsob # smaže každou osmou řádku gsed '0~8d' # pouze GNU sed sed 'n;n;n;n;n;n;n;d;' # ostatní sedy # smaže řádky obsahující "pattern" sed '/pattern/d' # smaže všechny prázdné řádky ze souboru (jako "grep '.' "" sed '/^$/d' # 1. způsob sed '/./!d' # 2. způsob # pokud je víc prázdných řádek po sobě, smaže je až na první # smaže prázdné řádky ze začátku souboru (namísto "cat -s") sed '/./,/^$/!d' # 1. způsob, nenechá mezeru na začátku, 1 u EOF sed '/^$/N;/\n$/D' # 2. způsob, nechá 1 mezeru na začátku, 0 u EOF # smaže všechny po sobě jdoucí prázdné řádky až na první dvě sed '/^$/N;/\n$/N;//D' # smaže prázdné řádky na začátku souboru sed '/./,$!d' # smaže všechny prázdné řádky na konci souboru sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' # běží na všech sedech sed -e :a -e '/^\n*$/N;/\n$/ba' # taktéž, až na gsed 3.02.* # smaže poslední řádku všech odstavců sed -n '/^$/{p;h;};/./{x;/./p;}' SPECIÁLNÍ POUŽITÍ: # odstraní formátováni nroff (znak, backspace - pro ztučnění písma) # z manuálových stránek. Příkaz 'echo' může v Unix System V shellu # a v bash shellu vyžadovat přepínač -e. sed "s/.`echo \\\b`//g" # dvojité uvozovky jsou v Unixu nutností sed 's/.^H//g' # v bash/tcsh, stiskni Ctrl-V a pak Ctrl-H sed 's/.\x08//g' # hex výraz pro sed 1.5, GNU sed, ssed # vypíše hlavičku zprávy pro Usenet/e-mail sed '/^$/q' # smaže vše po první prázdné řádce # vypíše tělo zprávy Usenet/e-mail sed '1,/^$/d' # smaže všechno do první prázdné řádky # vypíše pole Předmět, ale odstraní úvodní část "Subject: " sed '/^Subject: */!d; s///;q' # vypíše hlavičku pro návrat zprávy sed '/^Reply-To:/q; /^From:/h; /./d;g;q' # oddělí hlavičku s e-mailovou adresou # (viz předchozí skript) sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//' # přidá znak "> " na začátek každé řádky - citace zprávy sed 's/^/> /' # smaže úvodní "> " ze začátku každé řádky - zrušení citace sed 's/^> //' # odstraní většinu HTML tagů sed -e :a -e 's/<[^>]*>//g;/zipup.bat dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat TYPICKÉ POUŽITÍ: Sed na vstupu příjímá jeden nebo více přikazů a aplikuje je postupně na každou řádku vstupu. Poté co je řádka zpracována je předána na standartní výstup. Předchozí přiklady předpokládají vstup ze standartního vstupního zařízení (roura, apod...). Jeden, nebo více souborů mohou být specifikovány na přikazové řádce, pokud vstup není ze stdinu. Výstup je odeslán na stdout. cat filename | sed '10q' # na vstupu roura sed '10q' filename # to samé, bez cat sed '10q' filename > newfile # výstup přesměrován na disk Pro dalši informace o syntaxi doporučujeme knihy: sed & awk, 2nd Edition - Dale Dougherty and Arnold Robbins (O'Reilly,1997) UNIX Text Processing - Dale Dougherty and Tim O'Reilly (Hayden Books, 1987) nebo tutoriály od Mika Arsta viz - U-SEDIT2.ZIP. (všude možně) Pro ovládnuti mocného nástroje sed musíte znát Regulárni výrazy: Mastering Regular Expressions" by Jeffrey Friedl (O'Reilly, 1997) Manuálové stránky jsou také užitečné. Nikoliv sice pro laika, poslouží však skvěle jako reference. Zkuste "man sed", "man regexp", nebo podsekci "man ed". SYNTAXE UVOZOVEK: Předchozí příklady užívají jednoduché uvozovky ('...') namísto uvozovek dvojitých ("..."), protože je sed doma především na Unixových systémech. Jednoduché úvozovky zabrání shellu aby bral v potaz znak ($). Také pozor na kombinaci (`...') uvnitř ("..."). Uživatelé "csh" shellu a jemu podobných budou muset ke správnému běhu příkladů zauvozovkovat také (!) se zpětným lomítkem (\!). DOSové verze sedu vyžadují ("..."). POUŽITÍ '\t' VE SKRIPTECH: Pro přehlednost jsme v příkladech používali výraz '\t' pro vyjádření tabulátoru (0x09) ve skriptech. Nicméně, většina verzí sedu zkratku '\t' nepozná, raději tedy používejte klávesu TAB. '\t' je podporován jako regulární znak v awku, perlu a HHsedu, sedmodu a GNU sedu verze3.02.80. VERZE SEDU: Verze sedu se liší a drobné rozdíly mezi nimi jsou patrné. Většina nepodporuje značky (:name) nebo skokové přikazy (b,t) uvnitř příkazu, pokud nejsou na konci. Když se používá co nejpřenosnější syntaxe příkazy mohou být i poněkud kostrbaté: sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d v porovnání s rešením v GNU sedu: sed '/AAA/b;/BBB/b;/CCC/b;d' # nebo dokonce sed '/AAA\|BBB\|CCC/b;d' Navíc pamatujte, že zatímco mnoho sedů podporuje příkaz "/one/ s/re1/re2" mnoho NEpodporuje příkaz "/one/! s/re1/re2/" s mezerou před "s". Snažte se onu mezeru nepoužívat. OPTIMALIZACE PRO RYCHLOST: Pokud je nutné zvýšit výkonnost (velké soubory, apod.) je vhodné dát před příkaz "s" výraz "/hledej/" : sed 's/foo/bar/g' filename # standartní substituce sed '/foo/ s/foo/bar/g' filename # mnohem rychlejší sed '/foo/ s//bar/g' filename # zkrácená syntaxe Pokud chcete vypsat jen kus souboru, je velmi vhodné použít příkaz "q". Ten velmi urychlí práci s velkými soubory. sed -n '45,50p' filename # vypíše řádky 45 - 50 sed -n '51q;45,50p' filename # to samé, jen o dost rychleji Máte-li nějaké další skripty, které byste rádi publikovali, nebo objevili-li jste chybu v tomto dokumentu, kontaktujte prosím autora. Připojte vaší verzi sedu, operační systém a podstatu problému. Aby mohl být Váš skript prohlášen za "one-liner" (jednořádkáč :-) musí být kratší (nebo roven) 65 znaků. Naše díky patří: Al Aab # zakladatel "seders list"u Edgar Allen # všelicos Yiorgos Adamopoulos # leccos Dale Dougherty # autor "sed & awk" Carlos Duarte # autor "do it with sed" Eric Pement # autor tohoto dokumentu Ken Pizzini # autor GNU sedu verze 3.02 S.G. Ravenhall # skvělý "de-html" skript Greg Ubben # příklady a pomoc -------------------------------------------------------------------------