首页 > 解决方案 > 设置变量等于范围内的模式匹配

问题描述

我的目标

我需要匹配文本范围内的两行,以便我可以使用一行来设置 URL 以 curl 和另一匹配来设置输出文件名。如果任何一个模式在范围内都不匹配,那么我只想打印一个错误并继续。

示例输入

Non matching lines

<article>
Non matching lines
<h4 class="audio-module-title">A title</h4>
Non matching lines
<li class="audio-tool audio-tool-download"><a href="https://example.com/file.mp3"
</article>

Non matching lines

最终,我的目标是遍历所有文本范围,并为每个构造一个 curl 命令:

curl https://example.com/file.mp3 -o "A Title.mp3"

我认为 awk 是正确的选择,但我无法弄清楚如何做到这一点。我已经能够找到范围并过滤除匹配行之外的所有行,但我不确定如何处理其余部分。

awk '/<article>"/,/<\/article/ {if (/<h4 class=/)print } {if (/<li class="audio-tool audio-tool-download">/)print }' inputfile

标签: curlawk

解决方案


$ cat tst.sh
awk '
BEGIN { OFS="\t" }
/<article>/   { f=1 }
/<\/article>/ { f=0 }
f {
    if ( sub(/.*<h4 class="audio-module-title">[[:space:]]*/,"") ) {
        sub(/[[:space:]]*<\/h4>.*/,"")
        if ( title != "" ) {
            printf "Error@%s[%d]: Got title %s but no URL.\n", FILENAME, titleFnr, title | "cat>&2"
        }
        title = $0
        titleFnr = FNR
    }
    else if ( sub(/.*<li class="audio-tool audio-tool-download">[^"]+"/,"") ) {
        sub(/".*/,"")
        url = $0
        if ( title != "" ) {
            print url, title
        }
        else {
            printf "Error@%s[%d]: Got URL %s but no title.\n", FILENAME, FNR, url | "cat>&2"
        }
        title = url = ""
    }
}
END {
    if ( title != "" ) {
        printf "Error@%s[%d]: Got title %s but no URL.\n", FILENAME, titleFnr, title | "cat>&2"
    }
}
' "$1" |
while IFS=$'\t' read -r url title; do
    echo curl "$url" -o "${title}.mp3"
done

.

$ ./tst.sh file
curl https://example.com/file.mp3 -o A title.mp3

echo在初始测试后对输出感到满意时删除。


推荐阅读