Como as referências anteriores correspondem no sed?

4

Encontrei um comando sed de uma linha neste site, que remove entradas duplicadas em $PATH . Existe um conceito que não consigo entender. Ele usa correspondências salvas na seção de correspondência para detectar a duplicação e, em seguida, substitui a correspondência por .

No exemplo abaixo, não consigo entender por que nem sempre é 1111 . O caso de teste obviamente mostra que a combinação progride mais abaixo no espaço padrão, mas não consigo entender o porquê.

sed script ( sed_cmd ):

p  #debug
:b
s/[:;]\([^:;]*\)\([:;].*\)[;:]/;yyxx/p
s/[yx]//g   #debug remove the field indicators for the next pass
s/;/:/g     #debug
tb
s/^\([^:]*\)\(:.*\):/FixedFirst/
aDone

Teste de comando + saída:

echo "0000:1111:2222:3333:4444:1111:2222:3333:0000" | sed -f sed_cmd
0000:1111:2222:3333:4444:1111:2222:3333:0000
0000;y1111yx:2222:3333:4444x:2222:3333:0000
0000:1111;y2222yx:3333:4444x:3333:0000
0000:1111:2222;y3333yx:4444x:0000
0000:1111:2222:3333:4444FixedFirst
Done
    
por dpinvidic 10.07.2014 / 19:26

1 resposta

3

O padrão no comando substituto é: [:;]\([^:;]*\)\([:;].*\)[;:] . Observe o no final. Isso significa que qualquer texto corresponde ao primeiro grupo, \([^:;]*\) também deve ocorrer no final do padrão.

Seu espaço de padrão é inicialmente 0000:1111:2222:3333:4444:1111:2222:3333:0000 . O padrão corresponde a :1111:2222:3333:4444:1111 e 1111 corresponde ao primeiro grupo e também a no final.

Após a primeira rodada de substituições, o espaço padrão foi alterado para 0000:1111:2222:3333:4444:2222:3333:0000 . Agora, se o 1111 no espaço de padrão for usado para corresponder a \([^:;]*\) , não haverá 1111 para corresponder a . Assim, o padrão não corresponde e o mecanismo de regex tenta outra coisa. Nesse caso, usando a próxima correspondência disponível para o primeiro grupo, 2222 , funciona.

    
por 10.07.2014 / 19:54