用 awk/sed 替换一行,但只知道该行的一部分

用 awk/sed 替换一行,但只知道该行的一部分

我想在 Shell 脚本中做一些事情而不添加依赖项,所以必须依赖 awk/sed。

也就是说,我想替换文件中一行的内容,而不影响文件的其余部分。但我只知道该行的开头。例如,该行可能是

CURRENT_DATE 2020-03-02

或者它可以是

CURRENT_DATE 2019-04-01

或者任何其他日期 - 我唯一知道的是它以 CURRENT_DATE 开头。我想把实际的当前日期放在那里。该行位于文件的中间,不应影响其他行。

那么我该怎么做呢?虽然 sed 是典型的替换,但由于所需的通配符,我有点迷失了。

答案1

$ cat file
foo
CURRENT_DATE 2020-03-02
bar

$ sed 's/^\(CURRENT_DATE\).*/\1 '"$(date +'%F')"'/' file
foo
CURRENT_DATE 2020-07-17
bar

$ awk -v d="$(date +'%F')" '$1=="CURRENT_DATE"{$2=d} 1' file
foo
CURRENT_DATE 2020-07-17
bar

答案2

echo 'CURRENT_DATE 2020-03-02' |
    awk '/^CURRENT_DATE/ { print "CURRENT_DATE " strftime("%Y-%m-%d"); }'

CURRENT_DATE 2020-07-17

答案3

确保你匹配整条线,这样......

  • ^行的开头
  • CURRENT DATE不变的文本
  • [0-9]{4}应该是一年的东西,20[0-2][0-9]如果您愿意,可以将其更改为细化年份
  • (-[0-9]{2}){2}两组看起来像一个月和一天的组-
  • $行尾

所以

cat file 

foo
CURRENT_DATE 2020-03-02
bar
banana CURRENT_DATE 2020-03-02
CURRENT_DATE 2020-03-02 banana

awk '/^CURRENT_DATE [0-9]{4}(-[0-9]{2}){2}$/{$2=strftime("%Y-%m-%d")}1' file

或者

sed -E "s/^(CURRENT_DATE )[0-9]{4}(-[0-9]{2}){2}$/\1"$(date +'%F')"/" file

两者都产生

foo
CURRENT_DATE 2020-07-18
bar
banana CURRENT_DATE 2020-03-02
CURRENT_DATE 2020-03-02 banana

如果我们真的愿意,我们可以使用正则表达式或算术更深入地验证日期

awk '$1=="CURRENT_DATE"&&NF==2{
    split($2,d,"-");
    if (d[1]*d[2]*d[3]>0&&d[1]<2021&&d[2]<13&&d[3]<32)$2=strftime("%Y-%m-%d")}1' file

只是为了好玩日期验证(包括闰年)

awk '$1=="CURRENT_DATE"&&NF==2{
    if (split($2,d,"-")==3 && d[1]*d[2]*d[3]>0){
      leapyear=((d[1]%4==0&&d[1]%100!=0)||(d[1]%400==0))?1:0;     
      month=d[2]+int(d[2]/8);
      monthdays=(30+month%2-((month==2)?2-leapyear:0)))*(month<14);
      now=strftime("%Y-%m-%d");
      if ($2<=now&&d[3]<=monthdays)$2=now
      }}1' file

答案4

下面的命令匹配正则表达式并替换

猫文件

CURRENT_DATE 2020-03-02
CURRENT_DATE 2019-04-01
praveen
ajay
abhi
san
2019-04-01

命令

sed "/^CURRENT_DATE/s/CURRENT_DATE.*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/CURRENT_DATE $(date +%Y-%m-%d)/g"  file

输出

CURRENT_DATE 2020-07-18
CURRENT_DATE 2020-07-18
praveen
ajay
abhi
san
2019-04-01

Python

#!/usr/bin/python
import re
import datetime
from datetime import date
cu=date.today()
k=re.compile(r'^CURRENT_DATE [0-9]{4}-[0-9]{2}-[0-9]{2}')
m=open('file','r')
for g in m:
    if re.search(k,g):
        ou=re.sub(k,"CURRENT_DATE {0}".format(cu),g)
        print ou.strip()
    else:
        print g.strip()

输出

CURRENT_DATE 2020-07-18
CURRENT_DATE 2020-07-18
praveen
ajay
abhi
san
2019-04-01

相关内容