Unir vários comandos sed em um script para processar o arquivo CSV

28

Ter um arquivo CSV como este:

HEADER
"first, column"|"second "some random quotes" column"|"third ol' column"
FOOTER

e procurando resultados como:

HEADER
first, column|second "some random quotes" column|third ol' column

em outras palavras, removendo "FOOTER", aspas no começo, fim e ao redor |.

Até agora, esse código funciona:

sed '/FOOTER/d' csv > csv1 | #remove FOOTER
sed 's/^\"//' csv1 > csv2 | #remove quote at the beginning
sed 's/\"$//' csv2 > csv3 | #remove quote at the end
sed 's/\"|\"/|/g' csv3 > csv4 #remove quotes around pipe

Como você vê, o problema é que ele cria 4 arquivos extras.

Aqui está outra solução, que tem como objetivo não criar arquivos extras e fazer a mesma coisa em um único script. Não funciona muito bem.

#!/bin/ksh

sed '/begin/, /end/ { 
        /FOOTER/d
        s/^\"//
        s/\"$//
        s/\"|\"/|/g 
}' csv > csv4
    
por Bor 12.09.2015 / 14:36

2 respostas

34

Antes de mais nada, como Michael mostrou, você pode combinar tudo isso em um único comando:

sed '/^FOOTER/d; s/^\"//; s/\"$//; s/\"|\"/|/g' csv > csv1

Acho que algumas implementações de sed não conseguem lidar com isso e podem precisar de:

  sed -e '/^FOOTER/d' -e 's/^\"//' -e 's/\"$//' -e 's/\"|\"/|/g' csv > csv1

Dito isso, parece que seus campos estão definidos por | e você só quer remover " em todo o campo, deixando os que estão dentro do campo. Nesse caso, você poderia fazer:

$ sed '/FOOTER/d; s/\(^\||\)"//g; s/"\($\||\)//g' csv 
HEADER
first, column|second "some random quotes" column|third ol' column

Ou com o GNU sed :

sed -r '/FOOTER/d; s/(^|\|)"//g; s/"($|\|)//g' csv 

Você também pode usar o Perl:

$ perl -F"|" -lane 'next if /FOOTER/; s/^"|"$// for @F; print @F' csv 
HEADER
first, column|second some random quotes column|third ol' column
    
por 12.09.2015 / 14:53
12

Isso também funcionaria:

sed 's / ^ "//; s /" | "/ | / g; s /" "$ /" /'

Exemplo:

$ echo '"this"|" and "ths""|" and "|" this 2"|" also "this", "thi", "and th""' | 
sed 's/^"//; s/"|"/|/g; s/""$/"/'
this| and "ths"| and | this 2| also "this", "thi", "and th"

versão bonita

sed '
s/^"//
s/"|"/|/g
s/""$/"/
$d
'
    
por 12.09.2015 / 16:00

Tags