如何在每一行前添加一个用 awk 找到的模式实例

How to prepend each line with an instance of a pattern found with awk

我有一个包含很多行的文件。有些行显示日期和时间,例如2022-03-16-08:00

我希望找到的所有遵循该模式的行都预先添加了该模式

此外,因为有很多行的时间不同,所以我希望针对模式的每个实例进行更改,并在该实例的以下行前面添加相应的日期和时间。

例如,我有以下文件(example.txt):

Date1: 2022-03-16-08:00
Something happened
Something else happened
Date2: 2022-03-16-08:10
Something happened
Something else happened
Something else happened

而我想要的结果是:

Date1: 2022-03-16-08:00
2022-03-16-08:00 Something happened
2022-03-16-08:00 Something else happened
Date2: 2022-03-16-08:10
2022-03-16-08:10 Something happened
2022-03-16-08:10 Something else happened
2022-03-16-08:10 Something else happened

我尝试使用 sed 将找到的模式添加到每一行之前,但 sed 变量似乎不起作用:

sed -e '/2022-/s/\(.*\)//' -e 's/^//' example.txt

结果:

Date1: 2022-03-16-08:00
Something happened
Something else happened
Date2: 2022-03-16-08:10
Something happened
Something else happened
Something else happened

我认为使用 awk 可能是可行的,使用 awk -F: '/2022/{var=$2}' 然后将其添加到下一行,但我不知道如何将其更改为 Date

的新实例

非常欢迎任何帮助。

我将 GNU AWK 按照以下方式完成此任务,令 file.txt 内容为

Date1: 2022-03-16-08:00
Something happened
Something else happened
Date2: 2022-03-16-08:10
Something happened
Something else happened
Something else happened

然后

awk 'BEGIN{FPAT="[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}:[0-9]{2}"}NF{when=;print}!NF{print when,[=11=]}' file.txt

输出

Date1: 2022-03-16-08:00
2022-03-16-08:00 Something happened
2022-03-16-08:00 Something else happened
Date2: 2022-03-16-08:10
2022-03-16-08:10 Something happened
2022-03-16-08:10 Something else happened
2022-03-16-08:10 Something else happened

说明:在 BEGIN 内部,我使用 FPAT(字段模式)通知 GNU AWK 它应该将字段视为以下字符串:4 位数字后跟 -然后是 2 位数字,然后是 -,然后是 2 位数字,然后是 -,然后是 2 位数字,然后是 :,然后是 2 位数字,即时间戳符合您正在使用的格式。对于每一行,如果它确实包含这样的文件(即 NF 的字段数是 non-zero),请为第一个这样的字段(</code>)的内容设置 <code>when 变量值并按原样执行 print 当前行,如果没有这样的字段(!NFNF 的否定)然后打印 when 变量值后跟整个当前行( [=29=]).

警告:我的代码假设如果你在单行中有多个时间戳,你想使用第一个并且第一行总是有时间戳

(在 gawk 4.2.1 中测试)

此解决方案应该适用于 awk 的任何版本:

awk -F ': ' 'NF == 2 &&  ~ /^20[0-9]{2}/ {
   dt = ; print; next} {print dt, [=10=]}' file.log

Date1: 2022-03-16-08:00
2022-03-16-08:00 Something happened
2022-03-16-08:00 Something else happened
Date2: 2022-03-16-08:10
2022-03-16-08:10 Something happened
2022-03-16-08:10 Something else happened
2022-03-16-08:10 Something else happened

使用您显示的示例,请尝试以下 awk 代码。在 GNU awk 中编写和测试,应该在任何 awk.

中工作
awk '
match([=10=],/[0-9]{4}(-[0-9]{2}){3}:[0-9]{2}/){
  value=substr([=10=],RSTART,RLENGTH)
  print
  next
}
{
  print value,[=10=]
}
'  Input_file

使用sed:

sed -e '/: 2[0-9]\{3\}-/{p;s/.*: //;h;d;}' -e 'G;s/\(.*\)\n\(.*\)/ /' example.txt