如何在每行前面加上 awk 找到的模式实例

发布于 2025-01-14 17:04:16 字数 1092 浏览 1 评论 0原文

我有一个包含很多行的文件。有些行显示日期和时间,例如 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/\(.*\)/\1/' -e 's/^/$1/' example.txt

结果:

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

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

任何帮助都是值得赞赏和非常欢迎的。

I have a file with many lines. Some lines display the date and time, e.g. 2022-03-16-08:00

I want all lines following the pattern found to have that pattern prepended

In addition, because there are many lines with different times, I want this to change for every instance of the pattern, and prepend the following lines of that instance with the respective date&time.

For example, I have the following file (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

And the result I want is:

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

I tried with sed to prepend the pattern found to each other line, but the sed variable doesn't seem to work:

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

Result:

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

I thought that it may be feasible with awk, to take the pattern with awk -F: '/2022/{var=$2}'
and then prepend it to the next lines, but I don't know how I would change it to the new instance of Date

Any help is appreciated and very welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

臻嫒无言 2025-01-21 17:04:16

我将按照以下方式让 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=$1;print}!NF{print when,$0}' 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 内部我通知 GNU AWK 使用 FPAT (字段 PATtern),它应该将字段视为以下字符串:4 位数字,后跟 - 后跟 2 位数字,后跟 -< /code> 后接 2数字后跟 - 后跟 2 位数字,后跟 : 后跟 2 位数字,即时间戳符合您正在使用的格式。对于每一行,如果它确实包含此类文件(即 NF 的字段数量非零),请为第一个此类字段的内容设置 when 变量值(>$1) 并按原样 print 当前行,如果没有这样的字段(!NFNF 的否定) 然后打印 when 变量值,后跟整个当前行($0)。

警告:我的代码假设如果您在单行中有多个时间戳,您希望使用第一个时间戳,并且第一行中始终有时间戳

(在 gawk 4.2.1 中测试)

I would GNU AWK for this task following way, let file.txt content be

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

then

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

output

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

Explanation: Inside BEGIN I inform GNU AWK using FPAT (Field PATtern) that it should consider field to be following string: 4 digits followed by - followed by 2 digits followed by - followed by 2 digits followed by - followed by 2 digits followed by : followed by 2 digits, i.e. timestamp compliant with format you are using. For each line if it does contain such file (i.e number of fields that is NF is non-zero) do set when variable value for content of 1st such field ($1) and do print current line as is, if there is not such field (!NF that is negation of NF) then do print when variable value followed by whole current line ($0).

Warning: my code assume that if you have more than one timestamp in single line you want to use first one and there is always timestamp in first line

(tested in gawk 4.2.1)

牛↙奶布丁 2025-01-21 17:04:16

使用 sed:

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

Using sed:

sed -e '/: 2[0-9]\{3\}-/{p;s/.*: //;h;d;}' -e 'G;s/\(.*\)\n\(.*\)/\2 \1/' example.txt
不念旧人 2025-01-21 17:04:16

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

awk -F ': ' 'NF == 2 && $2 ~ /^20[0-9]{2}/ {
   dt = $2; print; next} {print dt, $0}' 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

This solution should work in any version of awk:

awk -F ': ' 'NF == 2 && $2 ~ /^20[0-9]{2}/ {
   dt = $2; print; next} {print dt, $0}' 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
骄兵必败 2025-01-21 17:04:16

对于显示的示例,请尝试执行以下 awk 代码。在 GNU awk 中编写和测试,应该可以在任何 awk 中工作。

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

With your shown samples, please try following awk code. Written and tested in GNU awk, should work in any awk.

awk '
match($0,/[0-9]{4}(-[0-9]{2}){3}:[0-9]{2}/){
  value=substr($0,RSTART,RLENGTH)
  print
  next
}
{
  print value,$0
}
'  Input_file
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文