
Arquivo de entrada:Contém 3 colunas com a 3ª coluna sendo a data no DD-MMM-YYYY
formato
de dados de amostra:
1232,abdc, 02-Jan-2014
4534,kdafh, 20-Feb-2014
364,asjhdk, 11-Jul-2012
saída necessária:
1232,abdc, 2014-01-02
4534,kdafh, 2014-02-20
364,asjhdk, 2012-07-11
usando a função data: date -d 20-DEC-2014 +%Y-%m-%d
usei o comando awk dá erro
Existe alguma outra maneira?
Responder1
Uma resposta possível usando o awk, assumindo que o arquivo de entrada seja input-file.txt e o arquivo de saída seja output-file.txt :
awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d "$3" +%Y-%m-%d");}' input-file.txt > output-file.txt
Responder2
UsandoMoleiro( mlr
) para limpar o excesso de espaço em branco na entrada CSV sem cabeçalho e reescrever o terceiro campo. O terceiro campo é reescrito analisando a data fornecida usando strptime()
a string de formato de hora %d-%b-%Y
e, em seguida, reformatando o carimbo de data/hora Unix resultante usando strftime()
a %F
string de formatação (você pode usar, por exemplo, %Y-%m-%d
no lugar de %F
):
mlr --csv -N \
clean-whitespace then \
put '$3 = strftime(strptime($3,"%d-%b-%Y"),"%F")' file
Dados os dados da pergunta, isso resultaria
1232,abdc,2014-01-02
4534,kdafh,2014-02-20
364,asjhdk,2012-07-11
Se seus dados tiverem um carimbo de data/hora no mesmo campo, você poderá ajustar as strings de formato usadas nas chamadas strptime()
e strftime()
para atender às suas necessidades.
Consulte o manual strftime
do seu sistema para ver o que essas strings de formatação significam e quais são suas opções para formatar datas e horas.
Responder3
Supondo que o texto de entrada seja assim:
1232,abdc, 02-Jan-2014 18:01:37</br>
4534,kdafh, 20-Feb-2014 07:17:19</br>
364,asjhdk, 11-Jul-2012 23:20:30</br>
minha resposta seria:
cat input-file.txt | sed 's[</br>[[g' | awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d \""$3" "$4"\" +\"%Y-%m-%d %H:%M:%S\"");}' > output-file.txt
E se os registros estiverem em uma única linha (nenhuma nova linha no arquivo de entrada após o </br>, seria
cat input-file.txt | sed 's[</br>[\n[g' | awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d \""$3" "$4"\" +\"%Y-%m-%d %H:%M:%S\"");}' > output-file.txt
Responder4
Você não quer criar um novo processo que execute um shell e outro comando para cada linha de um arquivo, isso seria muito ineficiente. Ter um código de interpretação do shell baseado na entrada também é uma receita para introduzir vulnerabilidades de injeção de comando. Além disso, essa -d
opção não é padrão.
Aqui, eu usaria uma ferramenta de processamento de texto que pode manipular o tempo, como Perl:
perl -MTime::Piece -pe '
s{\d+-\w+-\d+$}{Time::Piece->strptime($&, "%d-%b-%Y")->ymd}e
' < your-file
Lá, combinamos <digits>-<word-characters>-<digits>
encontrado no final da linha ( $
), interpretamos isso como <day>-<month-abbrev>-<year>
e reformatamos como <yead>-<month>-<day>
usando o módulo Time::Piece principal do perl.