Bash convertendo data em um arquivo csv com o awk ou outra ferramenta linux (csvcut)

3
awk -F"," '{OFS=","; $1=system("date -d "$1" +%d-%m-%Y") ; print $0}' data.csv | head 

Estou tentando obter a primeira coluna de um arquivo csv e padronizar o formato de data para% dd-% mm-% aaaa.

Quando eu tento o código acima, recebo data: erro de gravação: cano quebrado.

Mas quando eu tento o código abaixo:

dd=$(csvcut -c  1 -e ISO-8859-1 -d ","  data.csv | head -2 | sed -n 2p)
echo $dd
echo $(date -d $dd "+%d-%m-%Y")

Eu obtenho a saída:

2017-02-03

03-02-2017

O que estou fazendo errado? Alguma dica? Obrigado.

Meu sistema: Ubuntu 16.04.1 LTS

EDIT 2: aqui está um exemplo de arquivo: link

EDITAR:

arquivo de dados CSV (entrada): data.csv (com muitas linhas)

Bogført,Tekst,Beløb,Saldo  

2017-02-03, random text,-425,-611524.54  

saída:

Bogført,Tekst,Beløb,Saldo    
03-02-2017, random text,-425,-611524.54 

mas o formato de data pode estar em qualquer outro formato. No momento, estou procurando padronizar datas para um trabalho de importação de csv. Obrigado.

    
por Grzegorz Nowak 14.02.2017 / 04:36

3 respostas

1

Você está usando a função system() da maneira errada. Ou melhor, não é o que usar aqui, pois não retorna a saída do comando, apenas o status de saída (a saída vai para o terminal).

Assumindo que date seja GNU date , este é um script awk que executará a reformatação da data:

BEGIN { OFS = FS = "," }

$1 {
    cmd = sprintf("date -d '%s' '+%%d-%%m-%%Y' 2>/dev/null", $1);
    cmd | getline $1;
    print;
    close(cmd);
}

Executando:

$ awk -f script.awk data.csv
Bogført,Tekst,Beløb,Saldo
03-02-2017, random text,-425,-611524.54

O script descartará as linhas de entrada vazias. Ele cria uma string de comando cmd que faz a conversão de data real usando o GNU date . Erros de date serão descartados (e $1 permanecerá inalterado).

Para fazer isso com cvssql (de csvkit ):

$ sed '1,2d' data.csv | csvsql -H --query 'SELECT strftime("%d-%m-%Y", a), b, c, d FROM stdin' | sed '1d' >new_data.csv

Os dados em new_data.csv estarão sem a linha de cabeçalho. Para adicioná-lo de volta:

$ cat <( head -n 1 data.csv ) new_data.csv >even_newer_data.csv
    
por 14.02.2017 / 11:15
1

Como você está usando o Ubuntu, você provavelmente tem o GNU awk , que fornece funções úteis de data e hora:

echo "2017-03-02" | \
awk '{ gsub(/-/, " ", $1); t = mktime($1 " 0 0 0"); print strftime("%d-%m-%Y", t);}'
    
por 14.02.2017 / 08:07
1
bash-4.1$ cat a.txt
2017-02-03, random text,-425,-611524.54
2017-02-08, random text,-425,-611524.54
2017-02-07, random text,-425,-611524.54


bash-4.1$ awk -F, '{a="date -d "$1" +%Y%m%d"; while (a |getline line){$1=line;}print $0}' OFS=, a.txt
20170203, random text,-425,-611524.54
20170208, random text,-425,-611524.54
20170207, random text,-425,-611524.54

bash-4.1$ awk -F, '{a="date -d "$1" +%Y%m"; while (a |getline line){$1=line;}print $0}' OFS=, a.txt
201702, random text,-425,-611524.54
201702, random text,-425,-611524.54
201702, random text,-425,-611524.54

awk -F, 'NR==1{print;next}{a="date -d "$1" +%Y%m"; while (a |getline line){$1=line;}print $0}' OFS=, a.txt
    
por 14.02.2017 / 07:43