行中的子串

Xav*_*ros 1 sed awk text-processing

我有很多日志文件

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
Run Code Online (Sandbox Code Playgroud)

像这样的线条

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
Run Code Online (Sandbox Code Playgroud)

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

对于上面的示例,输出应如下所示

06Nov20 13:48:11 foobar.tif
Run Code Online (Sandbox Code Playgroud)

我最好的结果是

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


foobar.tif
foobar2.tif
foobar3.tif
...
Run Code Online (Sandbox Code Playgroud)

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

Adm*_*Bee 5

假设你有 GNUawk的第三个参数match(),你会想到以下程序:

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

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

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

对于你的例子,我得到

06Nov20 13:48:11.838: foobar.tif
Run Code Online (Sandbox Code Playgroud)

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

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

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


αғs*_*нιη 5

使用sed

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