Como posso substituir várias instâncias de um caractere pelo mesmo número de instâncias de um caractere diferente no linux sed?

2

Eu preciso substituir um conjunto repetido de caracteres (2 ou mais) pelo número exato de caracteres de substituição. Eu preciso fazer isso com sed, ou dentro do vi.

Exemplos

"abc,,,def" becomes "abc|||dev"
"1245d,,,,,22" becomes "1245d|||||22"

Obrigado

    
por xman 02.06.2017 / 08:07

3 respostas

1

Passe por sed , como

echo "abc,,,def" | sed 's/,/|/g'

mas eu recomendaria usar

tr ',' '|'

neste caso.

    
por 02.06.2017 / 08:38
1

Desculpe-me por não comentar, não tenho 50 reputação.

Esta solução falhará se houver mais padrões, como abc,,,def,g .

sed -n 's/[^,],,/&/;tsubs;p;d;:subs s/,/|/g;p' <<<'abc,,,def
abc,,def
abc,,,def,g
abc,def'
    
por 07.06.2017 / 06:03
0

Isso é praticamente impossível, devido à maneira como as expressões regulares funcionam. Como jvb já apontou, uma solução é simples (embora não necessariamente curta) se o número máximo de caracteres de origem consecutivos for conhecido. Se não, é possível alterar todos os caracteres de origem primeiro e, em seguida, alterar os caracteres únicos em um segundo passo. No entanto, isso só funciona se o caractere de destino não ocorrer no fluxo de entrada ou se você puder usar um caractere conhecido por não ocorrer no fluxo de entrada como um destino intermediário.

Além disso, você precisa considerar os casos de canto de um único caracter de origem que ocorrem no início ou no final da linha. Assim:

tr ',' '|' < file | sed 's/\([^|]\)|\([^|]\)/,/;s/^|\([^|]\)/,/;s/\([^|]\)|$/,/'

ou

sed 's/,/|/g;s/\([^|]\)|\([^|]\)/,/;s/^|\([^|]\)/,/;s/\([^|]\)|$/,/' file

Uma solução usando uma linguagem que tenha uma noção de tamanho de string seria mais robusta.

    
por 08.06.2017 / 16:40

Tags