Bash script / awk para ingresar y generar un archivo CSV
Tengo problemas para crear un script bash / awk / sed que tomaría un archivo CSV separado por comas de tres columnas (nombre, apellido, fecha de nacimiento) y generaría otro archivo CSV que tiene las mismas columnas de la entrada con un columna adicional que muestra la diferencia entre la fecha actual y la fecha de nacimiento en años.
$ yourscript <input CSV file> <output CSV file>
input.csv puede verse así:
bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972
output.csv debería verse así:
bob,wag,06/13/1958,62
ashley,hay,01/23/1983,37
evan,bert,09/11/1972,48
Respuestas
$ cat data
bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972
Para generar un archivo con nombre output-filey mostrarlo en STDOUT al mismo tiempo:
$ awk -v year=$(\date +%Y) 'BEGIN{FS="/"} {print $0 "," year-$3}' data | tee output-file
bob,wag,06/13/1958,62
ashley,hay,01/23/1983,37
evan,bert,09/11/1972,48
O simplemente enviar al mismo archivo:
$ awk -v year=$(\date +%Y) 'BEGIN{FS="/"} {print $0 "," year-$3}' data > output-file
Para realizar cálculos de tiempo más precisos, puede usar gawklas funciones de cadena y tiempo (según la sugerencia de @ AdminBee). Usando datos de entrada como:
$ cat data
bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972
Puede obtener una diferencia horaria en días entre ahora y la fecha que se muestra en cada línea, con:
$ awk -F, 'BEGIN{today=systime()}
{print $0 "," int((today-mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00))/(3600*24))}' \
data | tee output-file
bob,wag,06/13/1958,22755
ashley,hay,01/23/1983,13765
evan,bert,09/11/1972,17551
El fragmento:
int((today-mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00))/(3600*24))
hace tres cosas básicas para cada línea del archivo de entrada:
- calcula el tiempo transcurrido (en segundos) desde 1970-01-01 00:00:00 UTC (en sistemas POSIX), sin contar los segundos intercalares, con
mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00) - calcula la diferencia de tiempo entre la cantidad anterior y la variable
today, que contiene el número de segundos transcurridos en el momento de la ejecución desde 1970-01-01 00:00:00 UTC. - divide la diferencia de tiempo en segundos por 3600 * 24 para obtener lo mismo en días, y solo considera la parte entera del resultado, para obtener días completos
int().
Puedes jugar con eso para obtener tu diferencia de tiempo en segundos, minutos, horas según tus necesidades. HTH
Para obtener la diferencia de fecha, puede usar esta pequeña función bash
Utilice los siguientes números para sus necesidades
- #Para obtener diferencia de días : 86400
- #Para obtener años de diferencia: 31536000
Función Bash
datediff() {
current_date=$(date -d "$1" +%s)
birth_date=$(date -d "$2" +%s)
echo $(( (current_date - birth_date) / 31536000)) Years
}
Uso:
datediff '9/28/2020' '1/1/1999'
Salida:
21 years
Dependiendo de lo que realmente quieras:
años de diferencia:
(echo "firstname,lastname,d"; cat input.csv) | csv-sqlite \
"select *, strftime('%Y', 'now') - substr(d, 7, 4) as year_diff
from input" | csv-header --remove
años:
(echo "firstname,lastname,d"; cat input.csv) | csv-sqlite
"select *, strftime('%Y', 'now') - substr(d, 7, 4) -
case when strftime('%m%d', 'now') >= (substr(d, 1, 2) || substr(d, 4, 2))
then 0 else 1 end as age
from input" | csv-header --remove
csv-sqlite y csv-header son de csv-nix-tools