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
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
.
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
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