行中的子串

行中的子串

我有很多日志文件

workstation_2020_10_30-230600.log
workstation_2020_11_01-143352.log
workstation_2020_11_02-123203.log
workstation_2020_11_02-181803.log
workstation_2020_11_02-194433.log
workstation_2020_11_02-203701.log

像这样的线条

I 06Nov20 13:48:11.838: PrintConsole    PrintConsole(1) unknown 0   2386    ExposureStatusChanged: ExposureId=2386,ExposureName=foobar.tif,ExposureStatus=Successful,PercentComplete=100,GroupingCount=30,OrderingTimeout=0,IsComplete=True

我想检查IsComplete=True找到子字符串的所有行以提取时间戳和曝光文件的名称(在 后面说明ExposureName=)。

对于上面的示例,输出应类似于

06Nov20 13:48:11 foobar.tif

我最好的结果是

cat workstation/* | grep tif.*IsComplete=True | cut -d '=' -f 3 | cut -d ',' -f 1 | sort


foobar.tif
foobar2.tif
foobar3.tif
...

这没有给我时间戳。我不知道如何在不编写循环和函数的情况下轻松进行......

答案1

假设您使用 GNUawk作为 的第三个参数match(),则会想到以下程序:

awk '/IsComplete=True/{match($0,"ExposureName=([^,]+)",a); print $2,$3,a[1]}' *.log

这将匹配包含字符串的所有行IsComplete=True并提取模式 " ExposureName=,后跟任何不是," 的字符,并将后一部分(即文件名)放在将存储在数组变量中的捕获组中a

然后,它将打印第二个和第三个“单词”(空格分隔的字段),其中包含日期和时间,然后是调用中捕获组的内容match()

对于你的例子,我得到

06Nov20 13:48:11.838: foobar.tif

如果你想去掉时间戳的 ms 部分,你可以使用gensub()修改该字段:

awk '/IsComplete=True/{match($0,"ExposureName=([^,]+)",a); print $2,gensub(/\..*$/,"","1",$3),a[1]}' *.log

请注意,字段 ( $2, $3) 的编号很大程度上取决于空格的存在/不存在,因为这是awk默认情况下将行拆分为字段的方式;因此,如果时间戳格式发生更改(例如更改为06 Nov 20),您将需要调整print语句中的语法。

答案2

使用sed

sed -E '/IsComplete=True/{
     s/^[^ ]* ([^.]*)\..*ExposureName=([^,]*),.*/\1 \2/;
}' *.log

相关内容