regex 从固定模式字符串中提取多个值

ttp71kqs  于 2022-12-30  发布在  其他
关注(0)|答案(5)|浏览(147)

我想从wget命令输出的最后一位解析3条信息,例如:

2022-12-26 19:14:44 (13.7 Mb/s) - ‘somelibrary.min.js’ saved [1077022]

我能够得到日期/时间,因为这是一个固定的长度。我无法提取est.传输速度(13/7)和文件大小(1077022)的值。

STR="2022-12-26 19:14:44 (13.7 Mb/s) - ‘somelibrary.min.js’ saved [1077022]"
echo date/time is ${STR::19}

我想剩下的子字符串提取需要借助正则表达式来完成,但我无法找到它。是否有一条仅使用 *nix utils(如awk、sed等)的可行路径?
我试过awk:

echo "(13.7 Mb/s)" | awk '$0 ~ /(.* Mb\/s)/ {print $1}'

但是我得到的是(13.7而不仅仅是数字。

zphenhs4

zphenhs41#

您可以使用bash的正则表达式匹配来实现这一点,在RE中使用( )来捕获相关部分,然后使用${BASH_REMATCH[n]}来获取它们:

str="2022-12-26 19:14:44 (13.7 Mb/s) - ‘somelibrary.min.js’ saved [1077022]"

pattern='([-0-9]+ [:0-9]+) \(([^)]+)\) .*\[([0-9]+)\]'
if [[ "$str" =~ $pattern ]]; then
    echo "date/time is ${BASH_REMATCH[1]}"
    echo "transfer speed is ${BASH_REMATCH[2]}"
    echo "file size is ${BASH_REMATCH[3]}"
else
    echo "The string is not in the expected format"
fi

顺便说一句,我建议使用小写或混合大小写的变量名,以避免与具有特殊函数的许多全大写名称冲突,并通过shellcheck.net运行脚本以查找常见错误。

f2uvfpb9

f2uvfpb92#

这个awk应该适合您:

s="2022-12-26 19:14:44 (13.7 Mb/s) - ‘somelibrary.min.js’ saved [1077022]"
awk -F '[][()[:blank:]]+' '{
  printf "DateTime: %s %s, Speed: %s, Size: %s\n", $1, $2, $3, $(NF-1)
}' <<< "$s"

DateTime: 2022-12-26 19:14:44, Speed: 13.7, Size: 1077022
    • 细目:**
  • -F '[][()[:blank:]]+'[]()的1+或空白设置为输入字段分隔符
0mkxixxg

0mkxixxg3#

使用你展示的示例,请尝试以下awk代码。在GNU awk中编写和测试。这里是Online Demo用于使用正则表达式。

s="2022-12-26 19:14:44 (13.7 Mb/s) - ‘somelibrary.min.js’ saved [1077022]"

awk '
match($0,/([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}) \(([^)]*).*\[([0-9]+)/,arr){
  print "DateTime: "arr[1] ", Speed: " arr[2] ", Size: "arr[3]
}
' <<< "$s"
rhfm7lfc

rhfm7lfc4#

使用Perl和 * 命名捕获组 *:

s="2022-12-26 19:14:44 (13.7 Mb/s) - ‘somelibrary.min.js’ saved [1077022]"

perl -nE '
    say join "\n",
    map { "$_: $+{$_}" }
    keys %+
    if m/
        (?<dateTime>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\(
        (?<speed>\d+\.\d+).*\[
        (?<size>\d+)
    /x
' <<< "$s"

输出

speed: 13.7
dateTime: 2022-12-26 19:14:44
size: 1077022

解释

参见regex101 description

ctehm74n

ctehm74n5#

在更换中使用sed和3个捕获组\1\2\3

sed -E 's/([^()]+) \(([^()]*)\).*\[([^][]*)]/date\/time: \1\nspeed: \2\nfile size: \3/' file

模式匹配:

  • ([^()]+)捕获组1,匹配除()以外的任何字符
  • \(([^()]*)\)(...)之间捕获除组2中的()之外的任何字符
  • .*与行的其余部分匹配
  • \[([^][]*)][...]之间捕获组3中除[]之外的任何字符

regex101上查看此处的捕获组值
产出

date/time: 2022-12-26 19:14:44
speed: 13.7 Mb/s
file size: 1077022

相关问题