【问题标题】:Get specific string line from file bash从文件 bash 中获取特定的字符串行
【发布时间】:2020-11-07 20:07:05
【问题描述】:

我有一个带有这种带有模式的文本的文件

[{"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

我无法弄清楚如何在没有不必要符号的情况下从文件中正确获取所需的行

【问题讨论】:

  • jsons 不是有效的 json
  • @bigbounty 打错字,抱歉
  • 如果您处理真正的JSON 内容,您会发现许多 开源库和程序来处理它。但是你的问题中应该提到 JSON

标签: json bash sed grep jq


【解决方案1】:

使用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

【讨论】:

  • 我以前从未见过 jq 的-c 选项。我不得不说我喜欢它。但是,使用 $() 可能会导致 json 对象被切碎。考虑一下 baz 实际上只是一个空间的情况。引用字符串中的任何空格都可能有问题。我认为您可以使用 IFS="\n" 解决这个问题(不确定)。您可能还需要在 $k 周围加上双引号:-d "$k"
  • -c = compact instead of pretty-printed output;。添加在双引号内
  • 是的,while read -r json; do curl ... ; done &lt; "$(jq ...)" 会是更好的方法。
【解决方案2】:

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

jq -r '.[] | "curl -d '\'' \(.) '\''  http://restful.com/api " ' 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

.[] | "some string \(.)" 

第一个. 表示获取整个json 结构,[] 表示遍历结构中的每个数组元素。 | 是一个过滤器,用于处理数组中的每个元素。过滤器是输出一个字符串。我们使用\(.) 对传入| 过滤器的整个元素进行插值。

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

curl -d '<the json dictionary array element>' http://restful.com/api

好的。你会看到输出。有用。但是等一下,我们只有输出。让我们告诉 shell 像这样运行每一行:

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

通过管道输出到 bash,我们执行我们输出的每一行。本质上,我们正在使用 jq 编写一个 bash 脚本来 curl http://restful.com/api 将 json 元素作为 -d 数据参数传递给 POST json 元素。

重温单引号问题

@oguz ismail 指出,如果 json 输入文件中有单引号,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"}]

请注意上面的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,这样我就可以在不打扰http://restful.com/api 的人的情况下测试bash 脚本。

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

gsub( "\'" ; "\\\\\'" ) 

在进行替换后(' --> \'),我们将整个字符串通过管道传输到此:

"echo $\'\(.)\'" 

echo $''包围gsub的输出。现在我们再次使用 $' 以便 bash 正确理解 \'

所以当我们把卷曲放回原处时,我们就结束了:

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

【讨论】:

  • JSON 值中的单引号和 bash 卡住了。因此投反对票。
  • 使用 gsub() 解决了 @oguzismail 单引号,以转义可能在 jsonfile 输入中的单引号。答案现在太复杂了,表明这不是一个好方法,但它有效。
猜你喜欢
  • 2016-09-12
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
  • 1970-01-01
  • 2015-06-19
  • 2015-11-03
  • 2015-01-02
  • 1970-01-01
相关资源
最近更新 更多