我经常需要编写如下命令链:
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 中都是唯一的,或者将超时时间移至参数。如果您愿意,我们很乐意帮助您进行修改。