Solução bash pura
while IFS=\, read -r a b ; do echo "$a;$b" ; done <file.csv
Ou apenas por diversão
paste -d\; <(cut -d, -f1 file.csv) <(cut -d, -f1 --complement file.csv)
por exemplo eu tenho arquivo scv que parece
a1, b1, c1, d1
a2, b2, c2, d2
a3, b3, c3, d3
O que eu quero fazer é substituir a primeira vírgula ,
pelo ponto-e-vírgula ;
. A posição da primeira vírgula pode ser variável ( a
nas linhas n
e m
podem ter diferentes comprimentos). Finalmente meu arquivo será parecido com
a1; b1, c1, d1
a2; b2, c2, d2
a3; b3, c3, d3
As outras vírgulas devem permanecer. Alguém pode me dizer a solução mais simples?
PS minha solução não funciona: sed '/s/,/;/g' file.csv
O g
em:
sed 's/,/;/g'
é para globalmente , isto é, para substituir todas as ocorrências de ,
por ;
.
Se você quiser fazer apenas uma substituição por linha, tire o g
:
sed 's/,/;/'
E para completar:
Você também pode especificar qual ocorrência será substituída. Por exemplo, para substituir apenas a segunda ocorrência:
sed 's/,/;/2'
Com o GNU sed
, você também pode substituir todas as ocorrências a partir do segundo (na verdade, todas exceto a primeira) com:
sed 's/,/;/2g'
Para executar duas substituições, neste caso:
sed 's/,/;/;s/,/;/'
Quando fica mais complicado é quando o padrão pode corresponder à substituição (ou partes dela), por exemplo, ao substituir ,
por <,>
. sed
não possui mecanismo integrado para resolver isso. Você pode querer usar perl
nesse caso:
perl -pe '$i = 0; s/,/$i++ < 2 ? "<,>" : $&/ge'
perl -pe
é perl
sed
mode (observe que a sintaxe regex é diferente). Com o sinalizador e
do operador s///
, a substituição é considerada como código. Lá, substituímos ,
por <,>
apenas quando nosso contador incrementado for < 2. Caso contrário, substituiremos o ,
por si mesmo ( $&
, na verdade, referindo-se à sequência de correspondência como &
no comando sed
' s
).
Você pode generalizar isso para um intervalo ou um conjunto de substituições. Como para 3 rd a 5 th e 7 th a 9 th :
perl -pe '$i = 0; s/,/$i++;
$i >=3 && $i <= 5 || $i >= 7 && $i <= 9 ? "<,>" : $&/ge'
Suponho que seja um erro de digitação, mas o
sed '/s/,/;/g'
o comando que você escreveu na sua pergunta é algo completamente diferente.
Isso está fazendo:
sed '/start/,/end/g'
em que start
é s
e end
é ;
. Ou seja, aplicando o comando g
(substitua o espaço de padrão pelo conteúdo do espaço de suspensão (vazio aqui como você nunca contém nada)) para seções do arquivo entre uma que contenha s
e a próxima que contenha ;
.
Tags text-processing sed csv