sed, encontrar e colocar depois e antes

3

Tenho texto em massa com datas e horas diferentes, por isso não posso utilizá-lo como padrão e estava a pensar se é possível procurar o 1º , e DEPOIS imprimir " & procure por 2º , e ANTES de imprimir " . Deve ficar assim:

4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222

AGORA parece:

4,2014-05-08 18:22:24,14718202,4,184
4,2014-05-09 22:07:11,1278184,4,221
3,2014-05-05 10:01:24,1238461,1,222

Muito obrigado antecipadamente.

    
por ticket 17.03.2015 / 18:11

5 respostas

4

Uma maneira muito simplista é substituir a primeira e a segunda vírgulas como você disse:

sed 's/,/,"/;s/,/",/2' infile

, a menos que você queira corresponder a data (supondo que seja o mesmo formato em todas as linhas):

sed 's/\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\ [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\)/"&"/' infile

ou tudo entre a primeira e a segunda vírgula:

sed 's/^\([^,]*,\)\([^,]*\)\(,.*\)/""/' infile
    
por 17.03.2015 / 18:41
4

Você diz que deseja que o campo de data / hora seja citado?

awk 'BEGIN {FS=OFS=","} $2="\""$2"\""' infile > outfile 
    
por 17.03.2015 / 18:17
3

Outra maneira:

sed 's/,\([^,]*\),/,"",/' <infile >outfile

Isso não funcionará em nenhuma linha sem pelo menos duas vírgulas - portanto, ele ignorará completamente qualquer linha que não tenha pelo menos as duas. E sempre obterá apenas as duas primeiras vírgulas - porque os padrões básicos de regexp são aplicados com base na regra mais longa à esquerda - o que significa que uma correspondência é sempre feita como em breve quanto possível e por um tempo longo . Em outras palavras, a primeira vírgula encontrada em uma linha satisfará a primeira para a qual procuramos, e a próxima será sempre a que segue imediatamente a sequência mais longa de caracteres não-vírgula entre eles.

sed 's/,\([^,]*\),/,"",/
' <<\IN
4,2014-05-08 18:22:24,14718202,4,184
4,2014-05-09 22:07:11,1278184,4,221
3,2014-05-05 10:01:24,1238461,1,222
IN

Ele corresponde à primeira vírgula, seguido imediatamente por [^,]* zero-ou-mais * caracteres que são [^ não ,]* vírgulas, seguidos imediatamente por mais uma vírgula. \( groups \) corresponde a não-vírgula em uma subexpressão e faz referência a esse primeiro grupo de correspondência (e aqui apenas) no campo de substituição à direita da declaração s/// ubstitution. As vírgulas são substituídas por uma vírgula ," e uma cotação e uma cotação ", e uma vírgula, mas o grupo com referências anteriores se substitui. E então ...

OUTPUT

4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222

Ou você poderia fazer ...

sed '/,.*,/s/[^,]*/"&"/2' <infile >outfile

Isso torna o s/// ubstitution condicional - porque a substituição usada aqui poderia se aplicar a uma linha que corresponde apenas a uma vírgula - nesse caso, ele citaria tudo além dela. Para garantir que a substituição se aplique apenas a linhas que correspondam a pelo menos duas vírgulas, explicitamente /,.*,/ endereça somente linhas que correspondam a pelo menos uma vírgula seguida por zero ou mais * . caracteres de qualquer tipo e pelo menos mais uma vírgula, e somente nessas linhas s/// ubstitute a correspondência 2cd para [^,]* zero-or-more * não-vírgulas com & cercado por " de suas aspas.

Ele ainda teria o campo certo, mesmo se o primeiro caractere em uma linha fosse uma vírgula, como:

sed '/,.*,/s/[^,]*/"&"/2' <<\IN
,2014-05-05 10:01:24,1238461,1,222
IN

... que imprime ...

,"2014-05-05 10:01:24",1238461,1,222

... porque a primeira correspondência para zero ou mais caracteres não-vírgula é a cadeia de comprimento zero que ocorre antes da primeira vírgula.

    
por 17.03.2015 / 18:49
2

Você pode fazer isso com o awk:

awk 'BEGIN { FS = OFS = ","} { print $1, "\"" $2 "\"", $3, $4, $5 }' looks.txt > out.txt 
    
por 17.03.2015 / 18:18
1

Aqui está uma maneira sed :

$ sed -n 's/\(\([0-9]\|-\)* \([0-9]\|:\)*\)/\"\"/p' file.txt
4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222

Isso também funcionaria:

sed -n 's/\(.* \([0-9]\|:\)*\)/\"\"/p' file.txt
    
por 17.03.2015 / 18:29

Tags