如何有效地编写命令链(包括长查询/获取)?

如何有效地编写命令链(包括长查询/获取)?

我经常需要编写如下命令链:

curl api.example.com | jq '.files[].url' | xarg curl | grep 'Tel:\d+' > output

但这需要大量的反复试验:

curl api.example.com | jq '.file[]' # error
curl api.example.com | jq '.files[].url' # ok, continue
curl api.example.com | jq '.files[].url' | xarg curl | grep '\d+' # error
curl api.example.com | jq '.files[].url' | xarg curl | grep 'Tel:\d+' > output # ok

每次都编写一部分并运行将引发多个 HTTP 请求。

有什么方法/工具可以帮助我有效且高效地编写链?例如,可以缓存链的结果,直到其发生变化,memoize某种增量。

我当前的解决方案是将每个管道传输curl到一个文件,以便我可以从该文件运行解析,但这需要大量的手动工作:

curl api.example.com | jq '.file[]' # error
curl api.example.com | jq '.files[].url' # ok
curl api.example.com | jq '.files[].url' | xarg curl > temp
cat temp | grep '\d+' # error
cat temp | grep 'Tel:\d+' # ok
# It works! Now, compose the final chain again:
curl api.example.com | jq '.files[].url' | xarg curl | grep 'Tel:\d+' > output 

答案1

这确实很方便,但我不知道有这样的事。如果你的脚本可以处理一些样板,我可能会尝试这样的事情:

#!/bin/bash

set -eo pipefail

TIMEOUT=1
CACHE_FILE=/tmp/cache.tmp

req () {
    URL="$1"
    ARGS="${*:2}"
    if find "$CACHE_FILE" -mmin -${TIMEOUT} 2>/dev/null | grep . > /dev/null 2>&1; then
        echo "Using cache file" >&2
        cat "$CACHE_FILE"
    else
        echo "Making new request" >&2
        curl -s $ARGS "$URL" | tee "$CACHE_FILE"
    fi
}


req "https://base-template.squarespace.com/blog/?format=json-pretty" | jq ".website.id"

根据所需的灵活性,您可能需要调整缓存文件名,使其在每个 URL 中都是唯一的,或者将超时时间移至参数。如果您愿意,我们很乐意帮助您进行修改。

相关内容