如何在每一行前添加一个用 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
当前行,如果没有这样的字段(!NF
是 NF
的否定)然后打印 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
我有一个包含很多行的文件。有些行显示日期和时间,例如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
当前行,如果没有这样的字段(!NF
是 NF
的否定)然后打印 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