我有很多日志文件
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