Como substituir um caractere em um intervalo delimitado por dois outros caracteres de um arquivo

0

Eu preciso substituir todas as ocorrências do caractere de barra vertical | por uma vírgula , quando elas aparecerem entre [ e ] caracteres, em cada linha de um arquivo.

Digamos que eu tenha a string abaixo no arquivo:

wah wah| [go great|no great|so great] | wah wah | [go great|no great|so great]

Eu quero que minha saída seja como abaixo:

wah wah| [go great,no great,so great] | wah wah | [go great,no great,so great]

Observe que pode haver vários pares [ ... ] . Barras verticais entre o primeiro ] e o segundo [ não devem ser alteradas.

Como posso conseguir isso usando comandos shell? Eu tentei várias maneiras como abaixo, mas nada funcionou.

sed '/[/,/]/s/|/,/g' abcd.csv
    
por Anand 24.07.2018 / 23:29

1 resposta

2

Faça

sed ': loop; s/\(\[[^][]*\)|\([^][]*\]\)/,/; t loop' input_file

O que se passa?

  • : loop é um rótulo para looping; Eu vou usá-lo em um momento.
  • s/\(\[[^][]*\)|\([^][]*\]\)/,/ substitui um | que aparece entre [ e ] com uma vírgula. Dividido:

    s/  \(  \[  [^][]  *  \)  |  \(  [^][]  *  \]  \)  /  ,  /
    
    • \(\) delimita uma pesquisa & substitua o grupo. Dado um [] com um | entre eles, isso corresponde a [ a (mas sem incluir) o (ultimo) | como um grupo, e tudo após o | up até (incluindo) o ] como um segundo grupo.
    • \[ corresponde a um literal [ .
    • [^][] corresponde a qualquer caractere diferente de [ ou ] . Ele divide como
      [  ^  ][  ]
      , ou seja, uma instância de
      [^characters_to_not_match]
    • * - zero ou mais caracteres que não sejam [ ou ] .
    • \) - fim do grupo; discutido acima.
    • | é um literal | (aquele que queremos substituir).
    • A segunda metade da expressão regular é quase o mesmo que o primeiro semestre: corresponde a um grupo que consiste em zero ou mais caracteres diferentes de [ ou ] , seguido por um ] .
    • Em seguida, substitua tudo isso pelo primeiro grupo, uma vírgula e o segundo grupo. Como tudo na string correspondente está em um dos grupos, com exceção do | , isso substitui funcionalmente o \ pelo , .
  • t loop - teste / transferência. Se o comando s encontrou uma correspondência e fez uma substituição, volte para o marcador e tente novamente (porque o comando s substitui apenas um | de cada vez). Se não encontrou uma correspondência, termine o script de comando e vá para a próxima linha.
por 25.07.2018 / 00:52