4

我有一个文本文件,其内容重复大约 60 次,来自转换后的 .ics 文件:

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 的格式。我不想替换或重写整行,只是特定的字符串!欢迎使用任何提示、示例或链接,并且非常有用。

4

3 回答 3

2

试试这个(GNU sed):

sed -r 's/(Tijd ...: )(....)(..)(..).(..)(..)(..)./\1 \4.\3.\2 \5:\6:\7/' FILE
于 2012-04-12T15:27:40.797 回答
1

awk您的代码有几个问题:

  1. 虽然[:digit:]指的是“任何数字”,但您仍然需要另一对方括号 ( [...]) 来表示字符组:([[:digit:]]只是您想要的图像“ a,any digit or _ ”,这将是[a[:digit:]_]定义字符组的外部方括号。 )
  2. ;您的模式( /.../) 和相应的操作( ) 之间的分号 ( ){...}将两者分开,因此您有一个没有操作的模式,导致标准操作 {print $0},以及没有模式的第二个操作,导致它对所有记录执行(即线)。
  3. getline要求在继续之前awk阅读下一条记录(即行)。

将所有这些放在一起,您的代码将执行以下操作:

  • 打印所有匹配的行/^Tijd.*[:digit:][:digit:]Z$/(即没有,因为[:digit:]转换为“:,d,i,g, or 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":"sec}1' rooster2.txt

这工作如下:

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

请注意,GNUawk也有一个strftime功能。但是,这需要时间戳采用不同的格式。如果你想使用它,你仍然必须重新排列field,首先:

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即可更改格式。详情请参阅man strftime

于 2013-09-23T10:13:10.397 回答
0

作为红宝石单线;需要然后替换匹配的正则表达式timeTime.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
于 2012-04-12T15:43:41.973 回答