Formatação de data de arquivo CSV

1

Aqui está a versão curta da minha pergunta: como você converte listas de datas separadas por vírgula de um formato para outro? Mais especificamente, eu gostaria de um único comando de uma linha que converte strings desta forma:

YYYY/MM/DD,YYYY/MM/DD

para strings da seguinte forma:

DD/MM/YYYY,DD/MM/YYYY

Agora vou descrever o contexto da minha pergunta.

Eu tenho um arquivo CSV cujas linhas contêm pares de datas adjacentes no seguinte formato:

YYYY/MM/DD

Eu corro o seguinte comando grep para extrair o par de datas:

grep -Po '[1-2][0-1][0-9][0-9]/[0-1][0-9]/[0-1][0-9]','[1-2][0-1][0-9][0-9]/[0-1][0-9]/[0-1][0-9]' file.csv'

Isso resulta, por exemplo, em strings como as seguintes:

2016/05/16,2017/06/15

Eu posso converter uma única string de data usando o comando date da seguinte forma:

date -d '2016/05/16' '+%d/%m/%Y'

Isso produz o resultado desejado:

16/05/2016

Eu tentei aplicar esse comando a várias strings de entrada, por exemplo:

date -d"2016/05/16","2017/06/15" "+%d-%m-%Y"

Mas isso não funcionou. Recebi a seguinte mensagem de erro:

Error :- Invalid date - 2016/05/16,2017/06/15'

O que eu quero é um único comando que irá converter 2016/05/16,2017/06/15 para 16/05/2016,15/06/2017 .

    
por Kaushal 07.11.2017 / 13:09

2 respostas

1

Usando sed ...

echo "2016/05/16,2017/06/15" | sed 's/\([0-9]\{4\}\)\/\([0-9]\{2\}\)\/\([0-9]\{2\}\),\([0-9]\{4\}\)\/\([0-9]\{2\}\)\/\([0-9]\{2\}\)/\/\/,\/\//g'
16/05/2016,15/06/2017
    
por 07.11.2017 / 17:44
1

Aqui está uma solução que estende seu uso do comando date -d . Ele usa somente scripts de shell e as ferramentas de linha de comando padrão do GNU tr e paste :

tr ',' '\n' \
| while read line; do date -d "${line}" "+%d/%m/%Y"; done \
| paste -d, -s -

Usamos tr para converter a vírgula em uma nova linha, dividindo a única linha de entrada em duas. Em seguida, canalizamos essas duas linhas para um loop while e aplicamos o comando date formatting a cada linha. Finalmente, canalizamos as strings de data convertidas para paste , a fim de recombiná-las em uma única lista separada por vírgulas.

Aqui está o que parece com o seu exemplo de entrada:

echo 2016/05/16,2017/06/15 \
| tr ',' '\n' \
| while read line; do date -d "${line}" "+%d/%m/%Y"; done \
| paste -d, -s -

E aqui está a saída que produz:

16/05/2016,15/06/2017

Combinando isso com o comando grep em sua postagem, obtemos o seguinte:

grep -Po '[1-2][0-9][0-9][0-9]/[0-1][0-9]/[0-1][0-9]','[1-2][0-9][0-9][0-9]/[0-1][0-9]/[0-1][0-9]' file.csv \
| tr ',' '\n' \
| while read line; do date -d "${line}" "+%d/%m/%Y"; done \
| paste -d, -s -

Você também pode querer encurtar a expressão regular que está usando com grep . Talvez algo como isso também funcione (note que ele corresponde a uma vírgula final):

grep -Po '([12][0-9]{3}(/[01][0-9]){2},?){2}' file.csv

Finalmente, podemos usar o redirecionamento de saída para gravar os resultados em um arquivo:

grep -Po '[1-2][0-9][0-9][0-9]/[0-1][0-9]/[0-1][0-9]','[1-2][0-9][0-9][0-9]/[0-1][0-9]/[0-1][0-9]' file.csv \
| tr ',' '\n' \
| while read line; do date -d "${line}" "+%d/%m/%Y"; done \
| paste -d, -s - \
> new_file.csv
    
por 07.11.2017 / 13:23