Programování v shellu
sed

Lukáš Bařinka

Náplň cvičení

Cílem cvičení jsou textové transformace pomocí příkazu sed.

  • Příkaz sed
  • Vzory
  • Jednoduché příkazy
  • Substituce

Příkaz sed

sed overview
  • sed = Stream EDitor je řádkový programovatelný filtr
  • Pro řádku vstupu odpovídající vzoru se provede příkaz a výsledek se vypíše na výstup
  • Přepínač -n potlačí implicitní výpis výsledku
  • Části skriptu se oddělují ; nebo novým řádkem
  • Skript může být uložený v souboru (přepínač -f)
  • Prázdný skript
    
    									~alias 20='printf "%03d\n" {1..20}'
    									~20 | sed ''
    									~20 | sed -n ''
    									~20 | sed -f /dev/null
    									~20 | sed -n -f /dev/null
    								
  • Výpis konkrétního řádku
    
    									~20 | sed '10p'
    									~20 | sed -n '10p'
    									~20 | sed -n '10p;15p'
    									~20 | sed -n '10p
    									15p'
    								
  • sed skript
    
    									~vim skript
    									#!/bin/sed -nf
    									10p
    									15p
    
    									~20 | sed -nf skript
    
    									~chmod +x skript
    									~20 | ./skript
    
    
    
    									~./skript /etc/passwd
    								

Vzory

  • Příkazy lze omezit pomocí vzorů pouze na určité řádky:
    • prázdný vzor odpovídá každé řádce
    • n - číslo řádky
    • $ - poslední řádka
    • /RE/ - řádka odpovídající regulárnímu výrazu
    • od,do - rozsah řádků (včetně)
  • Prázdný vzor = všechny řádky
    
    									~20 | sed 'p'
    									~20 | sed -n 'p'
    								
  • Číslo řádku
    
    									~20 | sed -n '1p'
    									~N=10; 20 | sed -n "${N}p"
    								
  • Poslední řádek
    
    									~20 | sed -n '$p'
    								
  • Regulární výraz
    
    									~20 | sed -n '5p'
    									~20 | sed -n '/5/p'
    									~20 | sed -n '/0$/p'
    									~20 | sed -nr '/1+$/p'
    								
  • Rozsah
    
    									~20 | sed -n '5,10p'
    									~20 | sed -n '/0$/,$p'
    									~20 | sed -n '/1$/,/3$/p'
    									~20 | sed -n '/7$/,/1$/p'
    									~20 | sed -n '/018/,/018/p'
    								
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
						

Jednoduché příkazy

  • p - print (výpis řádky)
  • d - delete (smazání řádky)
  • q - quit (výpis řádky a ukončení skriptu)
  • = - line number (výpis čísla řádky)
  • p - print, explicitní výpis řádky
    
    									~20 | sed ''
    									~20 | sed 'p'
    									~20 | sed -n 'p'
    									~20 | sed -n '7,13p;/[02468]$/p'
    									~20 | sed -n '7,13p;/[02468]$/p' | uniq -d
    									~20 | sed -n '7,13p' | sed -n '/[02468]$/p'
    
    									~20 | sed -n '/[02468]$/p'
    									~20 | grep '[02468]$'
    								
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
						
  • d - delete, smazání řádky
    
    									~20 | sed 'd'
    									~20 | sed '10d'
    									~20 | sed '6,$d'
    									~20 | sed '1,/0$/d'
    
    									~20 | sed '/[02468]$/d'
    									~20 | grep -v '[02468]$'
    
    									~20 >soubor
    									~sed '10d' soubor; less soubor
    								
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
						
  • q - quit, ukončení skriptu (po případném implicitním printu)
    
    									~20 | sed 'q'
    									~20 | sed '10q'
    									~20 | sed '/0$/q'
    								
  • Q - quit, okamžité ukončení skriptu [GNU]
    
    									~20 | sed 'Q'
    									~20 | sed '10Q'
    									~20 | sed '/0$/Q'
    								
  • = - číslo aktuální řádky
    
    									~20 | sed '='
    									~20 | sed -n '='
    									~20 | sed -n '$='
    									~20 | sed '/0$/='
    								
001
002
003
004
005
006
007
008
009
010
011
...
						

Substituce

  • Na řádce je možné dělat náhrady textu příkazem s
  • s/RE/náhrada/[příznaky]
    • n - nahraď n-tý výskyt RE
    • g - nahraď všechny výskyty RE
    • p - pokud se náhrada provedla, vypiš řádku
  • Oddělovač částí je možné změnit na libovolný znak
  • Náhrada prvního výskytu na řádce
    
    									~20 | sed 's/010/deset/'
    									~20 | sed 's/$/./'
    									~20 | sed 's/0$/0 <--/'
    									~20 | sed 's/[05]$/& <--/'
    								
  • Náhrada n-tého výskytu na řádce
    
    									~20 | sed 's/0/x/'
    									~20 | sed 's/0/x/1'
    									~20 | sed 's/0/x/2'
    								
  • Náhrada všech výskytů na řádce
    
    									~20 | sed 's/0/x/g'
    								
  • Výpis po náhradě
    
    									~20 | sed -n 's/2/x/p'
    								
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
						
  • Náhrada s podvýrazy
    
    									~20 | sed 's/\(.\)\(.\)\(.\)/\3\2\1/'
    									~20 | sed -r 's/(.)(.)(.)/\3\2\1/'
    
    									~20 | sed -r 's/(.)(.)(.)/\1.\2.\3/'
    
    									~20 | sed -r 's/.(.)./(\1)/'
    									~20 | sed 's/..[05]$/--> &/'
    								
  • Náhrada RE na řádce odpovídající RE
    
    									~20 | sed '/[05]$/ s///'
    									~20 | sed '/[05]$/ s//& --/'
    									~20 | sed -n '/[05]$/ s//& --/p'
    								
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
						
  • Blok příkazů { ... }
    
    									~20 | sed -n '7,13p; /[02468]$/p'
    									~20 | sed -n '7,13 { /[02468]$/p; }'
    
    									~20 | sed -n '/[05]$/ {
    									s/^/--> /
    									s/$/ <--/
    									p
    									}'
    
    									~20 | sed -n '/[05]$/ { s/^/--> /; s/$/ <--/; p; }'
    								
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020