🎄mikrobloggeriet olormolorm-41 · olorm-42 · olorm-43

sed matching og betinget utførelse

“Match X og print Y=f(X)” er noe man ofte ønsker å gjøre. Eksempel:

echo 'Her er noe eksempeldata med
en linje med referanse til ref_123_bg og
en til ref_436_md osv.' > fil

Si at vi vil:

  1. Finn alle “ref_<ID>_<SUFFIX>
  2. Print <SUFFIX>:<ID>

En enlinjes sed-kommando for dette er:

#            Søkeuttrykk              Erstatning
#          ┌─┴─────────────────────┐ ┌┴──┐
sed -Ee 's/.*ref_([0-9]+)_([a-z]+).*/\2:\1/;t' -e d <fil
bg:123
md:436

Det jeg liker med denne er at vi bare trenger ett regulært uttrykk i skriptet.

Kommandoen t er det magiske her, det er seds eneste kommando for betinget flytkontroll.

UNIX PROGRAMMER’S MANUAL 1979

Fra dagens manual kan vi tilføye:

If label is not specified, branch to the end of the script.

Dette er grunnen til de to -e option-argumentene; vi trenger et “linjeskift” for å avslutte t uten label-argument.

Skrevet ut ser skriptet slik ut:

sed -E '
    s/.*ref_([0-9]+)_([a-z]+).*/\2:\1/    # erstatt *ref_X_Y* med Y:X
    t    # hvis erstatting skjedde, hopp til <label> (tom = slutten)
    d    # slett linje (hvis ikke hoppet over av forrige funksjon)
'        # de linjene som ikke slettes vil som default printes

Da jeg lærte denne komboen av -e og t (og b, betingelsesløs forgrening) syntes jeg den var akkurat så sær at jeg måtte legge den i mitt hjerte, og dele den med dere i dag.

Hva synes du?

—Richard Tingstad

P.S. Sett sammen med hold space omtalt tidligere så kan man kanskje skimte her at programmeringsspråket til sed er Turing-komplett.