Bash/AWK/SED匹配并重写一行中的数字字符串(日期)

Bash/AWK/SED匹配并重写一行中的数字字符串(日期),sed,awk,grep,Sed,Awk,Grep,我有一个文本文件,其中的以下内容从转换后的.ics文件中重复了大约60次: 启动Vak Tijd van:20120411T093000Z Tijd tot:20120411T100000Z Klas(sen)文档(en):VPOS0A1 VPOS0A2 Mariel Kers 瓦克:前瓦斯特。贝佩克。 洛卡尔:7.05 艾因德瓦克 我想重写“Tijd-van”和“Tijd-tot”值,使之成为一个好的日期(在带有awk、sed和grep等的gnu/linux系统上的bash脚本中)。我尝试使

我有一个文本文件,其中的以下内容从转换后的.ics文件中重复了大约60次:

启动Vak
Tijd van:20120411T093000Z
Tijd tot:20120411T100000Z
Klas(sen)文档(en):VPOS0A1 VPOS0A2 Mariel Kers
瓦克:前瓦斯特。贝佩克。
洛卡尔:7.05
艾因德瓦克
我想重写“Tijd-van”和“Tijd-tot”值,使之成为一个好的日期(在带有awk、sed和grep等的gnu/linux系统上的bash脚本中)。我尝试使用awk查找它:

awk'/^Tijd.[:digit:[:digit:]Z$/;{getline;打印$0;}'rooster2.txt
和格雷普:

egrep'/^Tijd(.*)[:digit:[:digit:]Z$/'rooster2.txt
但他们两人甚至都找不到界线

我想要的是将日期改写成一种更为简单/可行的时间格式,如EPOCH或类似2012年4月31日13:00:00的格式。我不想替换或重写整行,只想重写特定的字符串!任何东西,无论是提示,例子或链接都是受欢迎的,并且非常有用

试试这个(GNU-sed):


作为一个红宝石单衬里;需要
时间
时间。解析
然后替换
匹配regexp。您可以查看格式化时间的方法
输出

[slmn@uriel~]$ruby-rtime-ne'put$jd.sub(/(Tijd(van | tot):)(.*)/{$1+Time.parse($3.strftime(“%D%T”)}
您的
awk
代码有几个问题:

  • 虽然
    [:digit:][/code>指的是“任意数字”,但您仍然需要另一对方括号(
    […]
    )作为字符组:
    [:digit:][/code>(只是您想要的图像“a,任意数字或””,这将是
    [a[:digit:][/code>,定义字符组的外部方括号。)
  • 模式(
    /…/
    )和相应操作(
    {…}
    )之间的分号(
    )将两者分开,因此您有一个没有操作的模式,导致标准操作
    {print$0}
    ,第二个没有模式的操作,导致对所有记录(即行)执行该操作
  • getline
    要求
    awk
    在继续之前读取下一条记录(即行)
  • 将所有这些放在一起,您的代码将执行以下操作:

    • 打印与
      /^Tijd.[:digit:[:digit:][:digit:]Z$/
      匹配的所有行(这是无行,因为
      [:digit:][/code>转换为“其中一行:、d、i、g或t”)
    • 此外,对于所有行:阅读下一行并打印它
    因此,它将打印除第一行以外的所有行(因为这是唯一一行不是任何其他行的下一行)

    假设您只想打印匹配“以'Tijd'开头,以两位数字结尾,后跟一个'Z'”的行,您可以使用以下代码:

    awk'/^Tijd.[:digit:][:digit:]]Z$/{print$0;}'rooster2.txt
    
    由于
    {print$0}
    是标准操作,您甚至可以将其缩短为

    awk'/^Tijd.[:digit:][:digit:]]Z$/'rooster2.txt
    
    要解决实际问题,您可以使用以下方法:

    awk'/^Tijd.[:digit:][:digit:]Z$/{year=substr($NF,1,4);month=substr($NF,5,2);day=substr($NF,7,2);hour=substr($NF,10,2);min=substr($NF,12,2);sec=substr($NF,14,2);$NF=day.“month”。“year”“hour”:“min”:“sec1”rooster2.txt
    
    这项工作如下:

    • 对于匹配模式(
      /…/
      )的记录(即行),请根据需要重新排列最后一个字段(
      $NF
    • 打印所有记录(即行)(
      1
      是一种与所有记录(即行)匹配的模式,无需指定操作,从而生成标准记录(
      {Print$0}
    请注意,GNU
    awk
    还具有
    strftime
    功能。 但是,这需要时间戳采用不同的格式。 如果要使用该字段,必须重新排列字段,首先:

    awk-v FORMAT=“%c”/^Tijd.[:digit:][]Z$/{$NF=strftime(FORMAT,mktime(substr($NF,1,4)”“substr($NF,5,2)”“substr($NF,7,2)”“substr($NF,10,2)”“substr($NF,12,2)”“substr($NF,14,2))}1'rooster2.txt
    
    现在,您只需调整
    格式
    ,以满足更改格式的需要。
    有关详细信息,请参见
    man strftime

    我建议
    \2-\3-\4
    (例如2012-04-11)写入日期。它是明确的,并且在词汇和时间上都是一样的。谢谢!不知道塞德做得很好,谢谢!我已经试过了,但是我发现上面发布的sed更适合我的bash主题脚本。给了我更多的排序选项。谢谢
    sed -r 's/(Tijd ...: )(....)(..)(..).(..)(..)(..)./\1 \4.\3.\2 \5:\6:\7/' FILE
    
    [slmn@uriel ~]$ ruby -rtime -ne 'puts $_.sub(/(Tijd (van|tot): )(.*)/) { $1 + Time.parse($3).strftime("%D %T") }' < yourfile.txt
    Start Vak
    Tijd van: 04/11/12 09:30:00
    Tijd tot: 04/11/12 10:00:00
    Klas(sen) en Docent(en): VPOS0A1 VPOS0A2 Mariel Kers
    Vak: Ex. Verst. beperk.
    Lokaal: 7.05
    Einde Vak