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