Python 从周围文本不规则的行中提取浮动

Python 从周围文本不规则的行中提取浮动,python,awk,sed,grep,floating-point,Python,Awk,Sed,Grep,Floating Point,我有一个包含以下内容的文本文件: [silencedetect @ 0x7fa73cd000c0] silence_start: 1.32515 [silencedetect @ 0x7fa73cd000c0] silence_end: 1.88188 | silence_duration: 0.556735 [silencedetect @ 0x7fa73cd000c0] silence_start: 2.99698 [silencedetect @ 0x7fa73cd000c0] silen

我有一个包含以下内容的文本文件:

[silencedetect @ 0x7fa73cd000c0] silence_start: 1.32515
[silencedetect @ 0x7fa73cd000c0] silence_end: 1.88188 | silence_duration: 0.556735
[silencedetect @ 0x7fa73cd000c0] silence_start: 2.99698
[silencedetect @ 0x7fa73cd000c0] silence_end: 3.42311 | silence_duration: 0.426122
[silencedetect @ 0x7fa73cd000c0] silence_start: 5.58311
[silencedetect @ 0x7fa73cd000c0] silence_end: 6.13984 | silence_duration: 0.556735
[silencedetect @ 0x7fa73cd000c0] silence_start: 7.6729
size=N/A time=00:00:09.12 bitrate=N/A speed= 675x 
我想提取“silence\u start:”和“silence\u end:”位后面的值(即值1.32515、1.88188、…、7.6729)以及“time=”后面的值(即00:00:09.12)

我是grep/sed/awk的新手,正在尝试学习如何使用其中一个来实现这一点,但在苦苦挣扎之后,这一切都没有发生。我尝试过各种各样的想法,也上网浏览过,但我仍然没有成功。Python建议/解决方案也很好。我也试过了,结果一团糟

有人能帮忙吗?我将非常感激…提前谢谢你

使用GNU grep和(
-p
):

输出:

1.32515 1.88188 2.99698 3.42311 5.58311 6.13984 7.6729 00:00:09.12 1.32515 1.88188 2.99698 3.42311 5.58311 6.13984 7.6729 00:00:09.12
gnuawk解决方案:

 cat tst.awk
 {  s=gensub(/.*(time=|silence_(start|end): )([0-9.:]+).*/, "\\3", "g");
    print s
 }
sed -E 's/.*(silence_(start|end): |time=)([^[:space:]]+).*/\3/' file
解释正则表达式:

.*                              # anything
(                               # group 1 start
  time=                         # matching string "time="
  |                             # OR
  silence_(start|end):          # matching string "silence_start: "
                                # or "silence_end: " 
)                               # group 1 end
(                               # group 3 start
  [0-9.:]+                      # combination of number, "." and ":"
)                               # group 3 end
.*                              # anything
您可以将其用作:

$ awk -f tst.awk input.txt
1.32515
1.88188
2.99698
3.42311
5.58311
6.13984
7.6729
00:00:09.12
或作为oneliner:

 awk '{s=gensub(/.*(time=|silence_(start|end): )([0-9.:]+).*/, "\\3", "g"); print s}' input.txt

sed解决方案:

 cat tst.awk
 {  s=gensub(/.*(time=|silence_(start|end): )([0-9.:]+).*/, "\\3", "g");
    print s
 }
sed -E 's/.*(silence_(start|end): |time=)([^[:space:]]+).*/\3/' file
  • \3
    -指向第三个括号内的捕获的
    (…)
输出:

1.32515
1.88188
2.99698
3.42311
5.58311
6.13984
7.6729
00:00:09.12

当您的输入中有名称到值的映射时,一个解决方案首先创建这些映射的数组(例如下面的
n2v[]
),然后让您通过名称访问这些值,这通常被证明是最健壮的,并且在您的需求发生变化时最容易在将来增强:

$ cat tst.awk
BEGIN { FS="[ =]" }
{
    for (i=1; i<=NF; i++) {
        sub(/:$/,"",$i)
        n2v[$i] = $(i+1)
    }
    prt("silence_start")
    prt("silence_end")
    prt("time")
}
function prt(name) {
    if (name in n2v) {
        print name, n2v[name]
        delete n2v[name]
    }
}

$ awk -f tst.awk file
silence_start 1.32515
silence_end 1.88188
silence_start 2.99698
silence_end 3.42311
silence_start 5.58311
silence_end 6.13984
silence_start 7.6729
time 00:00:09.12

以上内容将适用于任何UNIX安装(或Windows,如果您有awk for Windows)上任何shell中的任何awk。

您能展示您目前所面临的困难吗?也许有人能帮你修复它们。。。