1. Introducció als entorns de treball UNIX

1.9. Accedir al contingut dels fitxers

1.9.3. Edició d’arxius amb l’editor de flux sed (stream editor)

El nom de l’ordre sed prové de stream editor (‘editor de flux’). Aquí, stream es refereix a les dades que es passen mitjançant tubs de shell. Per tant, la funcionalitat principal de l’ordre és actuar com un editor de text per a les dades d’entrada de l’entrada estàndard (stdin), amb la sortida estàndard (stdout) com el destí de sortida. També podem editar l’entrada d’un arxiu i guardar els canvis en el mateix arxiu si és necessari.

La sintaxi bàsica de sed és sed [options] {commands} {input-file}

La manera de treballar de sed és la següent: l’ordre sed llegeix la primera línia de l’{arxiu-de-entrada} i executa les {ordres} a la primera línia. Després llegeix la segona línia de l’{arxiu-de-entrada} i executa les {ordres} a la segona línia. L’ordre sed repeteix aquest procés fins que arriba al final de l’{arxiu-de-entrada}.

Editeu amb vi el fitxer test.bed i realitzeu cadascuna de les operacions que es mostren a continuació per entendre la potència de l’ordre sed:

$ cat test.bed
chr1 100 200
chr1 300 500
chr2 240 440
chr2 400 600
chr3 0 150

Alternativa:

chr1 100 200

chr1 300 500

chr2 240 440

chr2 400 600

chr3 0 150

Substitució

# Substitueix tots els strings que coincideixen amb chr1 per chr2

$ sed 's/chr1/chr2/' test.bed

chr2 100 200
chr2 300 500
chr2 240 440
chr2 400 600
chr3 0 150

# Substitueix tots els strings que coincideixen amb chr1 per chr2 només si la línia conté 300

$sed '/300/s/chr1/chr2/' test.bed
chr1 100 200 
chr2 300 500 
chr2 240 440 
chr2 400 600 
chr3 0 150

# Substitueix tots els strings que coincideixen amb chr1 per chr2 només si la línia no conté 300

$sed '/300/! s/chr1/chr2/' test.bed

chr2 100 200 chr1 300 500 chr2 240 440 chr2 400 600 chr3 0 150

# Reemplaça tots els strings que coincideixen amb chr si són els primers caràcters de la línia

$ sed 's/^chr//' test.bed
1 100 200

1 300 500

2 240 440

2 400 600

3 0 150

# Substitueix la primera ocurrència en cadascuna de les línies

$ sed 's/00/55/' test.bed
chr1 155 200

chr1 355 500

chr2 240 440

chr2 455 600

chr3 0 150

# Substitueix totes les ocurrències que coincideixin en el patró

$ sed 's/00/55/g' test.bed
chr1 155 255

chr1 355 555

chr2 240 440

chr2 455 655

chr3 0 150

# Imprimeix la línia on coincideix la substitució

$ sed -n 's/00/55/p' test.bed
chr1 155  200

chr1 355  500

chr2 455  600

# Es poden realitzar substitucions amb diferents flags simultàniament

$ sed -n 's/00/55/pg' test.bed
chr1 155  255

chr1 355  555

chr2 455  655

Eliminar

# Elimina la segona línia del fitxer

$ sed '2 d' test.bed
chr1 100 200

chr2 240 440

chr2 400 600

chr3 0 150

# Elimina de la línea 2 a la 4

$ sed '2,4 d' test.bed
chr1 100 200

chr3 0 150

# Elimina des de l’string chr1 a la línia 4

$ sed '/chr1/, 4 d' test.bed
chr3 0 150

# Elimina des de la primera línia que troba amb chr1 fins a la primera vegada que troba chr2

$ sed '/chr1/, /chr2/ d' test.bed
chr2 400 600

chr3 0 150

Edició implícita

El fitxer d’entrada i de sortida és el mateix. Feu-lo quan estiguis segur del canvi.

$ sed -i 's/00/55/g' test.bed
$ cat test.bed
chr1 155 255

chr1 355 555

chr2 240 440

chr2 455 655

chr3 0 150

Perquè el fitxer original ha canviat!

Substitucions regexp

Les expressions regulars són molt útils, i val la pena dedicar el temps per aprendre els conceptes bàsics. Es poden ampliar coneixements utilitzant eines en línia per construir i provar expressions regulars (per exemple, https://regex101.com/). A continuació enumerem algunes de les importants:

Àncores:

^ restringeix la coincidència a l’inici de la cadena.

$ restringeix la coincidència al final de la cadena.

Metacaràcters i quantificadors

  • . coincideix amb qualsevol caràcter, incloent-hi el caràcter de nova línia.
  • ? coincideix 0 o 1 vegada.
  • * coincideix 0 o més vegades.
  • +coincideix 1 o més vegades.
  • {m,n} coincideix de m a n vegades.
  • {m,} coincideix almenys m vegades.
  • {,n} coincideix fins a n (incloent-hi 0 vegades).
  • {n} coincideix exactament n.

Classes de caràcters:

  • [set123] coincideix amb qualsevol d’aquests caràcters una vegada.
  • [^set123] coincideix excepte amb qualsevol d’aquests caràcters una vegada.
  • [3-7AM-X] rang de caràcters des de 3 fins a 7, A, un altre rang des de M fins a X.
  • [[:digit:]] similar a [0-9] [[:alnum:]_] semblant a \w

# Elimina la primera columna: . defineix qualsevol caràcter després de chr

$ sed 's/^chr.//' test.bed
      100  200

      300  500

      240  440

      400  600

      0    150

# Elimina tots els zeros presents al fitxer

$ sed 's/0*//g' test.bed
chr1 1    2

chr1 3    5

chr2 24   44

chr2 4    6

chr3      15

# Elimina tots els números entre l’1 i el 3

$sed 's/[1-3]//g' test.bed
chr  00   00

chr  00   500

chr  40   440

chr  400  600

chr  0    50

# Substitueix l’string ch per res

$sed 's/[cr]//g' test.bed
h1   100  200

h1   300  500

h2   240  440

h2   400  600

h3   0    150

# S’utilitza qualsevol lletra entre la a i la z per res

$sed 's/[a-z]//g' test.bed
1    100  200

1    300  500

2    240  440

2    400  600

3              0     150

# Substitueix per la cadena que coincideix amb el patró

$ sed 's/^chr[0-9]/[&]/' test.bed
[chr1] 100 200

[chr1] 300 500

[chr2] 240 440

[chr2] 400 600

[chr3] 0 150

# Substitueix totes les ocurrències que encaixen en el patró i escriu al final de la línia '+'

$ sed 's/00/55/g ; s/$/\+/' test.bed
chr1 155 255 +

chr1 355 555 +

chr2 240 440 +

chr2 455 655 +

chr3 0 150 +

# Substitueix l’ocurrència que coincideix exactament amb 2 zeros

$ sed 's/0\{2\}/match/g' test.bed
chr1 1match    2match

chr1 3match    5match

chr2 240  440

chr2 4match    6match

chr3 0    150

# Substitueix l’ocurrència que coincideix amb 1 o 2 zeros

$ sed 's/0\{1,2\}/match/g' test.bed
chr1 1match    2match

chr1 3match    5match

chr2 24match   44match

chr2 4match    6match

chr3 match 15match

# Elimina totes les línies en blanc del fitxer

sed '/^$/ d' text.bed or sed '/^#/ d' test.bed