Em um arquivo de texto, desejo remover ,
(vírgulas) e também as "
(aspas) (somente se as aspas duplas contiverem números separados por vírgulas).
56,72,"12,34,54",x,y,"foo,a,b,bar"
Saída esperada
56,72,123454,x,y,"foo,a,b,bar"
Nota: Eu mostro a linha acima apenas como exemplo. Meu arquivo de texto contém muitas linhas, como acima, e os números separados por vírgulas presentes entre aspas duplas devem variar. Isso é,
56,72,"12,34,54",x,y,"foo,a,b,bar"
56,92,"12,34",x,y,"foo,a,b,bar"
56,72,"12,34,54,78,76,54,67",x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar","12,34,54"
56,72,x,y,"foo,a,b,bar","12,34,54","45,57,84,92","bar,foo"
Saída esperada:
56,72,123454,x,y,"foo,a,b,bar"
56,92,1234,x,y,"foo,a,b,bar"
56,72,12345478765467,x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar",123454
56,72,x,y,"foo,a,b,bar",123454,45578492,"bar,foo"
Existem n
vários números presentes entre aspas duplas, separados por vírgulas. E também deixe as aspas duplas que contêm caracteres como estão.
Eu amo a sed
ferramenta de processamento de texto. Fico feliz se você postar alguma sed
solução para isso.
text-processing
sed
csv
Avinash Raj
fonte
fonte
56,72,"12,34,54",x,y,"foo,a,b,bar"
para56,72,123454,x,y,"a,b"
,foo
ebar
é desaparecer. É o resultado desejado?foo
ebar
) são removidos junto com as vírgulas. Além disso, algumas citações desaparecem onde outras permanecem. Sem mencionar que as vírgulas entrea
eb
permanecem também. Existe algum padrão para isso?Respostas:
Isso (adaptado daqui ) deve fazer o que você precisa, embora o Perl one do @ rici seja muito mais simples:
Explicação
:a
: define um rótulo chamadoa
.s/(("[0-9,]*",?)*"[0-9,]*),/\1/
: Este precisa ser dividido(foo(bar))
,\1
seráfoobar
e\2
serábar
."[0-9,]*",?
: corresponde a 0 ou mais de0-9
ou,
, seguido por 0 ou 1,
.("[0-9,]*",?)*
: corresponde a 0 ou mais dos itens acima."[0-9,]*
: corresponde a 0 ou mais0-9
ou,
que vem logo após um"
ta;
: volte ao rótuloa
e execute novamente se a substituição tiver sido bem-sucedida.s/""/","/g;
: pós-processamento. Substitua""
por","
.s/"([0-9]*)",?/\1,/g
: remova todas as aspas ao redor dos números.Isso pode ser mais fácil de entender com outro exemplo:
Portanto, enquanto você pode encontrar um número logo após uma citação e seguido por vírgula e outro número, junte os dois números e repita o processo até que não seja mais possível.
Neste ponto, acredito que seja útil mencionar uma citação
info sed
que aparece na seção que descreve funções avançadas, como o rótulo usado acima (obrigado por descobrir se @Braiam):fonte
Se perl estiver OK, eis uma maneira curta (e provavelmente rápida, se não necessariamente simples :) de fazê-lo:
O
e
sinalizador para os:::
operador (que é apenas outra maneira de escrevers///
) faz com que a substituição seja tratada como uma expressão que é avaliada todas as vezes. Essa expressão pega a$1
captura do regex (que já está faltando as aspas) e a traduz (y///
que também pode ser escrita comotr///
) excluindo (/d
) todas as vírgulas. Or
sinalizador paray
é necessário para que o valor seja a sequência traduzida, em vez da contagem de traduções.Para aqueles que de alguma forma se sentem manchados por perl, aqui está o equivalente em python. O Python não é realmente uma ferramenta one-liner shell, mas às vezes pode ser convencido a cooperar. O seguinte pode ser escrito como uma linha (diferente dos
for
loops, que não podem ser), mas a rolagem horizontal torna (ainda mais) ilegível:fonte
y///
vez detr///
nos salvar mais um personagem.Para dados CSV, eu usaria um idioma com um analisador CSV real. Por exemplo, com Ruby:
fonte
Olá, aqui está o código Python para substituir vírgulas entre aspas duplas, vírgulas são substituídas pelo caractere pipe (|)
Este código Python deve substituir vírgulas entre aspas duplas
por exemplo: x, y, z, 1,2, "r, e, t, y", h, 8,5,6
se substituir pelo tubo x, y, z, 1,2, "r | e | t | y", h, 8,5,6
se substituir por nulo x, y, z, 1,2, "tentar novamente", h, 8,5,6
fonte