我有几个 ASCII 文件,其中有一列数据,如下:
DATA
1564
1896
1238
1479
1562
1894
1489
....
我需要实现一个包含日期的列。我知道每个数据集都是从1900-01-01(年-月-日)开始的。因此,我想按如下方式重新格式化每个文件:
DATE DATA
1900-01-01 1564
1900-01-02 1896
1900-01-03 1238
1900-01-04 1479
1900-01-05 1562
1900-01-06 1894
1900-01-07 1489
.....
我怎样才能做到这一点?
答案1
如果您有权访问 GNU date
,您可以执行以下操作:
$ ( date="1899-12-31"; printf 'DATE\tDATA\n';
tail -n+2 file |
while read line; do
date="$(date -d "$date + 1 day" +%F)"
printf '%s\t%s\n' "$date" "$line"
done; ) > newfile
解释
date="1899-12-31"
:将变量设置$date
为开始日期减去一天。printf 'DATE\tDATA\n';
:打印列标题。tail -n+2 file |
:打印除文件第一行(标题)之外的所有内容,并将其传递给循环while
。while read line; do ... ; done
:处理每个输入行,并将其另存为$line
.date="$(date -d "$date + 1 day" +%F)"
: 的值加一天$date
。printf '%s\t%s\n' "$date" "$line"
:打印当前值$date
和$line
变量。( ... ) > newfile
printf
:这使得整个命令在子 shell 中运行,因此您可以捕获第一个命令和循环的输出并将其重定向到newfile
.
答案2
#!/bin/bash
printf "DATE\tDATA\n"
offset=0
sed -n '2,$p' |
while read data; do
thedate=$( gdate -d "1900-01-01 + $offset days" +"%F" )
printf "%s\t%s\n" "$thedate" "$data"
(( ++offset ))
done
这个小脚本是用
$ bash script.sh <data
DATE DATA
1900-01-01 1564
1900-01-02 1896
1900-01-03 1238
1900-01-04 1479
1900-01-05 1562
1900-01-06 1894
1900-01-07 1489
它打印标题并跳过输入文件中的第一行输入(包含标题“ DATA
”)。
它使用 GNU(在我的系统上date
调用它,如果仅在您的系统上调用它,请更改该行)将当前行的日期计算为距 1900-01-01 的偏移量。gdate
date
然后,它以正确的格式输出计算出的日期以及从输入读取的数据,在两个制表符分隔的列中。