我正在尝试编写一个脚本,其中有一个与日期和一些字符串连接的列。我想将日期部分子字符串并与今天的日期进行比较。如果它比今天更旧,我想用今天的日期替换。这是一个例子。
cat test.txt
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161225O00001.0000
aaaa RR 242 644126 20161012O00001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161015O00001.0000
我想通过更改colum5 - 第3行和第7行的日期戳来获得如下输出。请帮忙。如果可能的话,我正在寻找单一的命令来使它工作。
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161225O00001.0000
aaaa RR 242 644126 20161020000001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161020000001.0000
答案 0 :(得分:2)
使用普通的Awk,因此不假设内置日期支持:
awk -v refdate="$(date +%Y%m%d)" '{ if ($5 < refdate) $5 = refdate substr($5, 9); print}'
给出数据文件和当前日期2016-10-20:
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161225O00001.0000
aaaa RR 242 644126 20161012O00001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161015O00001.0000
输出结果为:
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161225O00001.0000
aaaa RR 242 644126 20161020O00001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161020O00001.0000
答案 1 :(得分:0)
如果perl
没问题......注意:2016-10-21已经在我的世界里了;)
要使用Time::Piece
模块获取今天的日期:
$ perl -MTime::Piece -le '$d = localtime->ymd(""); print $d'
20161021
样本输入:
$ cat ip.txt
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161225O00001.0000
aaaa RR 242 644126 20161012O00001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161015O00001.0000
解决方案:
$ perl -MTime::Piece -pe 'BEGIN{$d=localtime->ymd("")} s/.* \K\d+/$& < $d ? $d : $&/e' ip.txt
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161225O00001.0000
aaaa RR 242 644126 20161021O00001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161021O00001.0000
BEGIN{$d=localtime->ymd("")}
将今天的日期保存在$d
变量中,仅在脚本开头执行此操作 s/.* \K\d+/$& < $d ? $d : $&/e
提取要替换的日期,与$d
进行比较,如果提取日期早于$d
,则替换为$d
.* \K
匹配到最后一个空格,使用\K
,此时匹配的文字将被丢弃
$&
包含来自\d+
e
标志允许在替换部分$& < $d ? $d : $&
而不是字符串
使用date
命令代替Time::Piece
模块:
perl -pe 'BEGIN{chomp($d=`date +%Y%m%d`)} s/.* \K\d+/$& < $d ? $d : $&/e' ip.txt
进一步阅读:
答案 2 :(得分:0)
在Gnu awk中(见解释中的最后评论):
$ awk -v a="$(date +%Y%m%d)" '(b=substr($5,1,8)) && sub(/^.{8}/,(b<a?a:b),$5)' file
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161225O00001.0000
aaaa RR 242 644126 20161021O00001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161021O00001.0000
说明:
awk -v a="$(date +%Y%m%d)" # set the date to a var
' # '
(b = substr($5,1,8) ) && # read first 8 chars of 5th field to b var
sub(/^.{8}/, (b<a?a:b), $5) # replace 8 first chars with a if b is less than a
# to make it compatible with other awks, change
# /^.{8}/ to /^......../
' file
答案 3 :(得分:0)
我终于想通了!谢谢詹姆斯,乔纳森和其他人。
这是我在solaris的命令。
$cat test.txt
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161012O00001.0000
aaaa RR 242 644126 20161013O00001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161014O00001.0000
$ /usr/xpg4/bin/awk -v a=`date +%Y%m%d` '(b=substr($5,1,8)) && gsub(/^.{8}/,(b<a?a:b),$5)' test.txt
aaaa RR 242 644126 20161030O00001.0000
bbbb RR 242 644126 20161022O00001.0000
aaaa RR 242 644126 20161022O00001.0000
aaaa RR 242 644126 20170129O00001.0000
aaaa RR 242 644126 20170326O00001.0000
aaaa RR 242 644126 20170430O00001.0000
aaaa RR 242 644126 20161022O00001.0000