Impor caractere entre caracteres repetidos

1

Dado uma string de caracteres ,,a,,,b,,,, , quero impor o caractere - no começo, se nenhum caractere for precedido por vírgula e entre cada vírgula que não tiver caractere. O que significa que o resultado é -,-,a,-,-,b,-,-,-,- . Agora eu já tentei:

echo ",,a,,,b,,,," | sed 's/,/,-/g' | sed 's/-\([^,]\)//g' | sed 's/^,/-&/g'

resultando em: -,-,a,-,-,b,-,-,-,-

Mas o problema é que invocar o sed 3 vezes é ineficiente em iterações muito longas . Existe uma maneira de fazer isso com o sed, provavelmente usando regex ou qualquer outra ferramenta invocando-o uma vez ?

    
por mark_infinite 14.05.2016 / 23:47

4 respostas

1

Um jeito de fazer isso em sed seria usar um loop:

$ echo ",,a,,,b,,,," | sed ':a; s/\(^\|,\)\(,\|$\)/-/; ta'
-,-,a,-,-,b,-,-,-,-

Se a sua versão suportar expressões regulares estendidas, você poderá simplificá-la para uma forma mais legível

sed -E ':a; s/(^|,)(,|$)/-/; ta'

Uma maneira alternativa de fazer isso em perl , dividindo em campos separados por vírgulas e, em seguida, mapeando campos vazios para hifens:

perl -anle 'print join ",", map { $_ ? $_ : "-" } split(",", $_, -1)'

(O argumento adicional -1 para o split força os campos vazios a serem incluídos).

    
por 15.05.2016 / 01:42
3
(echo ,,a,,,b,,,,; echo a,,b) | perl -pe 's/(^|,)\K(?=(,|$))/-/g' 
-,-,a,-,-,b,-,-,-,-
a,-,b

Acho que devo aprender sed um desses anos.

    
por 15.05.2016 / 00:40
1
echo ",,a,,,b,,,," |
  awk -v 'FS=,' -v 'OFS=,' '{for (i=1; i<=NF; i++) sub(/^$/,"-",$i); print};'
    
por 15.05.2016 / 00:48
0
$ echo ',,a,,,b,,,,' | sed 's/\(\([^,]\+,\)*\),/-,/g; s/\(^\|,\)$/-/'
-,-,a,-,-,b,-,-,-,-

A segunda expressão ( s/\(^\|,\)$/-/ ) é necessária apenas porque sed parece parar de corresponder quando atingiu o final do espaço de padrão, embora ainda possa corresponder a $ se a única expressão fosse s/\(\([^,]\+,\)*\)\(,\|$\)/-/g .

Claro, sed -E torna um pouco mais legível, mas de outra forma equivalente:

sed -E 's/(([^,]+,)*),/-,/g; s/(^|,)$/-/'
    
por 15.05.2016 / 02:56