我希望将curl
数据放入 shell 脚本变量中,然后使用cat
或awk
对该变量进行操作,就像它是一个文件一样。
这可能吗?或者有解决方法吗?我必须将curl
命令保存到文件中吗?
curl
对于我想要执行的每一位字符串格式化,我是否必须运行几次?
我正在curl
访问 ipinfo.io,想输出“city”和“region”的匹配行。我知道如何使用awk
并sed
根据需要格式化输出。
例如,尝试curl ipinfo.io/"8.8.8.8"
获取 Google DNS IP 地址的结果。
我只想打印“Mountain View”和“California”,最好在同一行,并采用一些常见的格式,例如“Mountain View, California”。
答案1
一般来说,有更合适的方法来解析 JSON 对象,但由于在这种情况下 JSON 对象非常简单,您可以将curl
的输出存储在变量中(这是可能的)并只需使用 AWK:
var="$(curl ipinfo.io/"8.8.8.8" 2>/dev/null)"
<<<"$var" awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
% var="$(curl ipinfo.io/"8.8.8.8" 2>/dev/null)"
% <<<"$var" awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
Mountain View, California
但是,除非您想curl
多次使用的输出,否则您可能只会使用管道:
curl ipinfo.io/"8.8.8.8" 2>/dev/null | awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
curl ipinfo.io/"8.8.8.8" 2>/dev/null | awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
Mountain View, California
<<<
是一种称为“此处字符串”的输入重定向形式;它将命令的 STDIN 从终端重定向到字符串。
这里发生的情况是,$var
在双引号之间扩展;AWK 命令的 STDIN 从终端重定向到扩展的字符串,然后 AWK 将该字符串读取为它的输入文件。
答案2
我希望将数据卷入 shell 脚本变量中,然后使用 cat 或 awk 对该变量进行操作,就像它是一个文件一样。这可行吗,或者有解决方法吗?
当然可以。如果内容不是太大,并且您想要运行多个命令来解析内容,那么将其缓存在内存中而不是每次都重新下载是件好事。
将结果存储curl
在变量中:
ipinfo=$(curl ipinfo.io/8.8.8.8)
要在其上运行命令:
<<< "$ipinfo" awk ...
<<< "$ipinfo" sed ...
双引号“$ipinfo”对于保留所有空格字符很重要。
不将内容保存在变量中的“解决方法”是找出一种在单个管道中处理内容的方法,例如@kos做过。
答案3
另一种更简单、更易读的方法是,你可以使用python
存在于所有基于 Linux 的系统中,为你解析 json
简单地说,导入json
和sys
包来加载json
对象,然后从对象打印result
您需要的任何属性:
curl ipinfo.io/"8.8.8.8" 2>/dev/null |
python -c 'import json,sys;
result=json.load(sys.stdin);
print(result["'city'"] + ", " + result["'region'"])';
我以更易读的方式添加了脚本,但是\
如果您需要将其写在多行中,则应该将其放在一行中或在每行末尾添加。
答案4
由于输出curl
将是 JSON,因此适当/更简单的工具似乎是jq
(轻量级且灵活的命令行 JSON 处理器):
$ curl ipinfo.io/"1.1.1.1" 2>/dev/null | jq --raw-output '"\(.city), \(.region)"'
White Hall, Alabama