É possível colocar aspas duplas em apenas algumas colunas usando sed?

1

Estou fazendo meu trabalho de conclusão de curso, onde preciso manipular algumas colunas de um arquivo .csv que tem seiscentas mil linhas. Já pesquisei em vários fóruns sobre sed e awk e não encontrei nada parecido (e infelizmente meu conhecimento sobre Linux não é muito profundo). O que eu encontrei geralmente lida com apenas uma coluna ou tudo ... o que eu preciso é colocar aspas duplas apenas na primeira, quinta e sexta colunas.

Por exemplo:

2018-03-18 4:56:17,255.255.255.255,00,ssh,admin,123

Para ser

"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"

Ainda assim, talvez eu ainda mudei algumas colunas, já que eu estou apenas começando em mineração de dados e não sei como será a configuração em algumas semanas, então se você puder fazer uma breve sintaxe de lógica, eu seja eternamente grato.

    
por Felipe Duarte 12.04.2018 / 02:15

4 respostas

4

Usando csvtool que tem um comando format útil:

csvtool format '"%1",%2,%3,%4,"%5","%6"\n' file.csv 

Exemplo:

echo "2018-03-18 4:56:17,255.255.255.255,00,ssh,admin,123" |
csvtool format '"%1",%2,%3,%4,"%5","%6"\n' -

Saída:

"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"

csvtool também pode call funções do shell e programas externos para analisar linhas de arquivos .CSV . Para fazer o mesmo usando printf , mas imprima o " 123 " em hexadecimal, faça:

echo "2018-03-18 4:56:17,255.255.255.255,00,ssh,admin,123" | 
csvtool call "printf '\"%s\",%s,%s,%s,\"%s\",\"%x\"\n'" -

Saída:

"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","7b"
    
por 12.04.2018 / 07:56
2

Eu poderia abordar isso com o awk dessa maneira:

  1. define o separador do campo de saída como o separador do campo de entrada, que atribuímos como a vírgula -F,
  2. para cada linha, reatribuir os valores dos campos 1, 5 e 6 como sendo os valores originais, mas entre aspas duplas. A aparente confusão de citações é porque usei aspas duplas para criar a string circundante, e como a única string que eu quero imprimir é uma aspa dupla, eu tenho que escapar, então cada aspas duplas que eu quero acaba sendo "\"" .
  3. Quando os campos tiverem sido atualizados, imprima a string recém-combinada.

O script é:

awk -F, 'BEGIN{ OFS=FS } {$1="\""$1"\""; $5="\""$5"\""; $6="\""$6"\""; print }' < input.csv > output.csv

Como você acha que precisa citar mais campos, simplesmente faça o mesmo que nos campos 1, 5 e 6 acima.

    
por 12.04.2018 / 03:10
1

com perl

$ perl -F, -lane 'map {$_=qq("$_")} @F[0,4,5]; print join ",", @F' ip.txt
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"
  • -F, use , como delimitador de campo de entrada, resultados disponíveis em @F array
  • map {$_=qq("$_")} @F[0,4,5] aspas duplas obrigatórias elementos da matriz. O índice começa em 0 . O operador qq é usado aqui para evitar o escape de aspas duplas, qq("$_") é o mesmo que "\"$_\""
  • print join ",", @F imprime a matriz modificada com , como separador


Outra maneira de fazer com awk

$ awk -v q='"' 'BEGIN{split("1 5 6",a); FS=OFS=","}
                {for(i in a) $a[i]=q $a[i] q} 1' ip.txt
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"
  • -v q='"' salve aspas duplas como valor em q variable
  • split("1 5 6",a) salvar o índice a ser alterado como valores em a array (divisão padrão no espaço em branco, o FS ainda não foi alterado)
  • FS=OFS="," altera o delimitador de entrada / saída para ,
  • for(i in a) $a[i]=q $a[i] q alterar campos obrigatórios
  • 1 maneira idiomática de imprimir o conteúdo de $0
por 12.04.2018 / 06:15
0

Se você realmente quiser usar sed (que eu não recomendo se awk ou perl estiverem disponíveis), presumindo que a sexta coluna seja terminada pela linha que termina em vez de uma vírgula E que campos não contêm vírgulas incorporadas (citadas):

sed -E -e 's/([^,]*),/"",/1' -e 's/([^,]*),/"",/5' -e 's/([^,]*)$/""/' file
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"

O padrão geral é s/([^,]*),/"",/n , em que n se refere à enésima ocorrência de zero ou mais caracteres não- , seguidos por , e é uma referência ao padrão capturado (entre parênteses) .

    
por 12.04.2018 / 03:15