Como posso trocar um valor em uma linha?

1

Se o valor for YES , torne-o NO . Se for NO , faça YES . Eu estou usando o seguinte comando como um exemplo:

( echo "online=YES"; echo "online=NO" ) | sed -e 's/online=YES/online=NO/' -e 's/online=NO/online=YES/'

online=YES
online=YES

Se o primeiro padrão for correspondido, ele deverá pular o segundo padrão. Isso seria equivalente ao next em awk .

    
por gary laxton 12.09.2017 / 22:56

3 respostas

4

sed -e 's/online=YES/online=NO/' -e t -e 's/online=NO/online=YES/'

O comando t em sed será ramificado para o rótulo fornecido (ou para o final do script sed se nenhum rótulo for fornecido) se um comando anterior s tiver feito uma substituição desde o mais recente leitura de uma linha de entrada.

Neste caso, ele ignorará a segunda substituição se a primeira substituição foi realizada.

Para o caso em que pode haver vários online=YES ou online=NO em linhas, use

sed -e 's/online=YES/online=MAYBE/g' \
    -e 's/online=NO/online=YES/g' \
    -e 's/online=MAYBE/online=NO/g' 

em que a string MAYBE não está associada ao padrão online= . Isso seria semelhante em natureza de usar uma variável temporária para trocar os valores de duas variáveis.

Teste:

$ echo "online=YES online=YES online=NO online=YES" | sed -e 's/online=YES/online=MAYBE/g' -e 's/online=NO/online=YES/g' -e 's/online=MAYBE/online=NO/g'
online=NO online=NO online=YES online=NO

O motivo pelo qual o comando n não funciona no lugar do comando t no primeiro exemplo é que ele lerá a próxima linha de entrada na metade do script e executará a segunda metade do script nessa linha:

$ ( echo "online=YES"; echo "online=YES" ) | sed -e 's/online=YES/online=NO/' -e n -e 's/online=NO/online=YES/'
online=NO
online=YES

Você obterá a mesma saída para duas linhas NO .

    
por 12.09.2017 / 23:00
0

Algumas técnicas perl :

perl -pe 's/online=\K(YES|NO)/$1 eq "YES" ? "NO" : "YES"/ge'
perl -pe 's/online=\K(YES(?{$r = "NO"})|NO(?{$r = "YES"}))/$r/g'

Veja esta resposta a uma questão relacionada para uma generalização da abordagem no segundo exemplo.

Aqui, você também pode usar um hash para definir uma tabela de conversão a ser aplicada à palavra seguinte online= :

 perl -pe 'BEGIN{%s = (YES => NO, NO => YES)}
           s{online=\K\w+}{$s{$&} // $&}ge'

Uma diferença em relação às soluções anteriores é que isso não alteraria online=YES1 para online=NO1 , pois verificaria YES em relação a YES1 (correspondido por \w+ ).

    
por 13.09.2017 / 08:41
0

Usando o comando t como @Kusalananda apontou, funciona para o seu exemplo (e para a maioria dos outros). Para realmente trocar duas strings em uma substituição, você pode fazer algo como

sed 'H;x;s/^/#NO#YES#NO/;s/.*#\(.*\)#\([^#]*\).*\n\(.*online=\)//'

Isso pode ser facilmente expandido para três ou mais strings para girar.

Para processar mais linhas, linhas, incluindo mais substituições ou linhas sem substituições, você pode expandi-las para fazer um loop sobre a substituição:

sed -e 'H;x;s/online=/&#/g;s/^/#NO#YES#NO#/;:a' -e 's/\(.*#\)\(.*\)#\([^#]*\)\(#.*\n\)\(.*online=\)#/#/;ta' -e 's/.*\n//'
    
por 13.09.2017 / 08:21

Tags