2016-10-20 46 views
1

我想在一個腳本,它有一個列連接日期和一些字符串。我想對日期部分進行子串處理並與今天的日期進行比較。如果它比今天更早,我想用今天的日期替換。這是一個例子。Unix命令用動態的當前日期替換舊的日期

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 
+1

因此,考慮到今天的日期是2016-10-20,如果數據的日期部分對應於2016-10-20之前的日期,那麼您希望將日期替換爲2016-10-20 ,但如果它是2016年或2017年或以後的未來日期,請保持獨立?日期可能從2015年或更早?日期字段後面的字母總是「O」,如您的示例中所示? –

+0

我試圖挽救格式並刪除示例中每行之間的空行。我想星號實際上也不是數據的一部分;你可否請審查,並[編輯]你的問題澄清? – tripleee

+0

從其他數據中分割日期似乎是促進您自己的理智並簡化下游處理的一種方式。 – tripleee

回答

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 : $&代替串使用代替Time::Piece模塊date命令:

perl -pe 'BEGIN{chomp($d=`date +%Y%m%d`)} s/.* \K\d+/$& < $d ? $d : $&/e' ip.txt 


延伸閱讀:

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 
+0

我在solaris中使用它。看起來像語法不接受 – Kate

+0

awk -v refdate =「$(date +%Y%m%d)」'{if($ 5 Kate

+0

如果您使用的是Solaris,問題可能是'$(...)'仍然無法被shell識別出來'使用(Solaris上的'/ bin/sh'是比時代晚了幾十年)。您可能需要使用:'''awk -v refdate ='date +%Y%m%d''{...}'test.txt'''。如果這不能解決問題,則需要查看Solaris Awk手冊頁並查看是否識別了substr。我認爲代替'$(...)'的back-ticks可能會解決這個問題,但如果不夠的話,還有更多的方法來調試。 –

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 
+0

它不在solaris中工作。 – Kate

+0

On Gnu awk?您是否嘗試過評論中的更改(未在Solaris上測試過)? –

+0

我不知道如何在solaris ksh中更改此部分子(/ ^。{8} /,(b Kate

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 
+0

/usr/xpg4/bin/awk -va ='date +%Y%m%d''(b = substr($ 5,1,8))&& gsub(/ ^。{8} /,(b Kate