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

时间:2012-04-12 15:17:39

标签: sed awk grep

我有一个文本文件,其中包含来自转换后的.ics文件的约60次内容:

Start Vak
Tijd van: 20120411T093000Z
Tijd tot: 20120411T100000Z
Klas(sen) en Docent(en): VPOS0A1 VPOS0A2 Mariel Kers
Vak: Ex. Verst. beperk.
Lokaal: 7.05
Einde Vak

我想重写“Tijd van”和“Tijd tot”值以成为一个好日期(在带有awk,sed和grep等的gnu / linux系统上的bash脚本中)。我试着用awk找到它:

awk '/^Tijd.*[:digit:][:digit:]Z$/; { getline; print $0; }' rooster2.txt

和grep:

egrep '/^Tijd(.*)[:digit:][:digit:]Z$/' rooster2.txt

但是他们俩都找不到这条线。

我想要的是将该日期重写为更多bash可解析/可行时间格式,如EPOCH或类似31.04.2012 13:00:00。我不想替换或重写整行,只需要特定的字符串!任何东西,无论是提示,示例或链接都是受欢迎的,非常有用。

3 个答案:

答案 0 :(得分:3)

试试这个(GNU sed):

sed -r 's/(Tijd ...: )(....)(..)(..).(..)(..)(..)./\1 \4.\3.\2 \5:\6:\7/' FILE

答案 1 :(得分:1)

作为红宝石单线;需要time Time.parse然后替换 匹配正则表达式。您可以查看strftime方法来格式化时间 输出

[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

答案 2 :(得分:1)

您的awk代码有几个问题:

  1. 虽然[:digit:]指的是“任何数字”,但您仍然需要另一对方括号([...])作为字符组:[[:digit:]](只是你想要的图像“ a,任何数字或_ ”,这将是[a[:digit:]_],外部方括号定义字符组。)
  2. 模式;)与相应的操作/.../)之间的分号({...})将两者分开,所以你有模式没有动作,导致标准动作 {print $0},第二个动作没有 pattern ,导致它对所有记录(即行)执行。
  3. getline要求awk在继续之前阅读下一个记录(即行)。
  4. 将所有这些结合在一起,您的代码将执行以下操作:

    • 打印与/^Tijd.*[:digit:][:digit:]Z$/匹配的所有行(即无,因为[:digit:]转换为“,d,i,g或t”之一。)
    • 此外,对于所有行:阅读 next 行并打印它。

    因此,它将打印除第一行之外的所有行(因为这是唯一一个不是 next 的行到任何其他行)。

    假设您只想打印匹配“以'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":"sec}1' rooster2.txt
    

    其工作原理如下:

    • 对于匹配模式/.../)的记录(即行),重新排列最后一个字段({{1} })满足您的需求。
    • 打印所有记录(即行)($NF模式,匹配所有记录(即行),未指定操作,产生标准的(1))

    请注意,GNU {print $0}也具有awk功能。 但是,这需要时间戳采用不同的格式。 如果您想使用它,您仍然必须重新排列字段,首先:

    strftime

    现在,您只需根据需要调整awk -v FORMAT="%c" '/^Tijd.*[[:digit:]][[: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 即可更改格式。 有关详细信息,请参阅FORMAT