Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 从文件bash获取特定的字符串行_Json_Bash_Sed_Grep_Jq - Fatal编程技术网

Json 从文件bash获取特定的字符串行

Json 从文件bash获取特定的字符串行,json,bash,sed,grep,jq,Json,Bash,Sed,Grep,Jq,我有一个文件,上面有这种带图案的文本 [{"foo":"bar:baz:foo*","bar*":"baz*","etc":"etc"}, {"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","etc":"etc"}, {&qu

我有一个文件,上面有这种带图案的文本

[{"foo":"bar:baz:foo*","bar*":"baz*","etc":"etc"},
{"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","etc":"etc"},
{"foo3":"bar3:baz3:foo3*","bar3*":"baz3*","etc":"etc"},
{"foo4":"bar4:baz4:foo4*","bar4*":"baz4*","etc":"etc"}]
我需要像这样拿每根绳子
{“foo”:“bar:baz:foo*”,“bar*”:“baz*”,“etc”:“etc”}
并通过curl将它们发送到某个url

for i in text.txt
do (awk,sed,grep etc)
then curl $string

我不知道如何在没有不必要的符号的情况下正确地从文件中获取所需的行

使用
jq
命令。这只是示例解析

for k in $(jq -c '.[]' a.txt); do
    echo "hello-" $k
done
输出:

hello- {"foo":"bar:baz:foo*","bar*":"baz*","etc":"etc"}
hello- {"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","etc":"etc"}
hello- {"foo3":"bar3:baz3:foo3*","bar3*":"baz3*","etc":"etc"}
hello- {"foo4":"bar4:baz4:foo4*","bar4*":"baz4*","etc":"etc"}
您可以在循环中的任意位置使用
$k

for k in $(jq -c '.[]' a.txt); do
    curl -d "$k" <url>
done
以美元表示的k的
(jq-c'.[]'a.txt);做
卷曲-d“$k”
完成

我建议您可以使用
jq
来处理json文件
jq
能够读取json并格式化输出。下面是一个处理json文件的示例
jq
脚本(我很难想象地称之为'jsonfile'):

以下是输出:

curl -d ' {"foo":"bar:baz:foo*","bar*":"baz*","etc":"etc"} '  http://restful.com/api 
curl -d ' {"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","etc":"etc"} '  http://restful.com/api 
curl -d ' {"foo3":"bar3:baz3:foo3*","bar3*":"baz3*","etc":"etc"} '  http://restful.com/api 
curl -d ' {"foo4":"bar4:baz4:foo4*","bar4*":"baz4*","etc":"etc"} '  http://restful.com/api 
下面是发生的事情:

我们将三个参数传递给
jq
程序:jq-r。
-r
告诉jq以原始格式输出结果(也就是说,请不要转义引号和其他内容)。 脚本如下所示:

.[] | "some string \(.)" 
jq -r '.[] | "curl -d '\'' \(.) '\''  http://restful.com/api " ' jsonfile | bash
第一个
表示获取整个json结构,
[]
表示遍历结构中的每个数组元素。
|
是一个过滤器,用于处理数组中的每个元素。过滤器将输出一个字符串。我们使用
\(.)
对传递到
\
过滤器中的整个元素进行插值

哇。。。我以前从未真正解释过
jq
脚本(它显示了这一点)。但关键是,我们使用jq查找json数组中的每个元素并将其插入字符串中。我们的字符串是:

curl -d '<the json dictionary array element>' http://restful.com/api
通过将输出管道化到bash,我们执行输出的每一行。本质上,我们正在编写一个带有jq的bash脚本,将json元素作为
-d
数据参数传递到POST json元素

单报价问题的再探讨 @oguz ismail指出,如果json输入文件中只有一个引号,bash将爆炸。这是真的。我们可以通过转义来避免引用,但是我们获得了更多的复杂性——这使得这是一种非理想的方法

以下是问题输入(我刚刚插入了一个引号):

注意上面的
baz
现在是
'baz
。问题是单引号会让bash shell抱怨引号不匹配:

$ jq -r '.[] | "curl -d '\'' \(.) '\''  http://restful.com/api " ' jsonfile | bash
bash: line 4: unexpected EOF while looking for matching `"'
bash: line 5: syntax error: unexpected end of file
以下是解决方案:

$ jq -r  $'.[] |    "\(.)"  | gsub( "\'" ; "\\\\\'" )  | "echo $\'\(.)\'" ' jsonfile     | bash
{"foo":"bar'baz:foo*","bar*":"baz*","etc":"etc"}
{"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","etc":"etc"}
{"foo3":"bar3:baz3:foo3*","bar3*":"baz3*","etc":"etc"}
{"foo4":"bar4:baz4:foo4*","bar4*":"baz4*","etc":"etc"}
上面我使用$''引用jq脚本。这使我可以使用“”来转义单引号。我还将
curl
命令更改为
echo
,这样我就可以测试bash脚本,而不会打扰
http://restful.com/api

“诀窍”是确保我们生成的bash脚本也用反斜杠转义所有单引号。因此,我们必须将
'
更改为
\'
。这就是gsub正在做的

gsub( "\'" ; "\\\\\'" ) 
在进行替换(
'
-->
\'
)之后,我们将整个字符串通过管道传输到以下位置:

"echo $\'\(.)\'" 
它用
echo$''
包围gsub的输出。现在我们再次使用$,因此bash可以正确理解
\'

所以当我们把卷曲放回去的时候,我们就这样结束了:

jq -r  $'.[] |    "\(.)"  | gsub( "\'" ; "\\\\\'" )  | "curl -d $\'\(.)\' http://restful.com/api " ' jsonfile     | bash

JSON无效json@bigbounty如果你处理真实的内容,你会发现很多开源库和程序可以处理它。但是你的问题中应该提到JSON,我以前从未见过jq的
-c
选项。我得说我喜欢它。但是,使用$()可能会导致json对象被切碎。考虑BAZ实际上只是一个空间的情况。带引号的字符串中的任何空格都可能有问题。我认为您可以使用IFS=“\n”(不确定)来解决这个问题。您可能还需要在$k周围加上双引号:
-d“$k”
-c=compact,而不是漂亮的打印输出。在读取-r json时添加了双引号Yeah,
;做卷曲;完成<“$(jq…”
将是一个更好的方法。JSON值中的一个引号和bash会被卡住。因此,downvote.Addressed@oguzismail单引号使用gsub()来转义可能在jsonfile输入中的单引号。现在的答案太复杂了,这表明这不是一个好方法,但它是有效的。
"echo $\'\(.)\'" 
jq -r  $'.[] |    "\(.)"  | gsub( "\'" ; "\\\\\'" )  | "curl -d $\'\(.)\' http://restful.com/api " ' jsonfile     | bash