假设我使用该命令find "$HOME" -maxdepth 1 -type d
,我得到以下结果:
/home/user/folder1
/home/user/folder2
/home/user/folder3
/home/user/folder4
我想jq
在管道上使用并创建不同的 JSON 行,如下所示:
{ "path": "/home/user/folder1", "type":"directory"}
{ "path": "/home/user/folder2", "type":"directory"}
{ "path": "/home/user/folder3", "type":"directory"}
{ "path": "/home/user/folder4", "type":"directory"}
jq
我希望通过避免将这个文件夹列表放在一个数组中并在循环中一个一个地创建它们来解决它。在伪代码中,这个想法是:
find "$HOME" -maxdepth 1 -type d | jq '.logic-to-create-json-strings'
有可能jq
吗?
此答案假定您的文件名(或您希望 JSON 编码的任何文本)是有效的 UTF-8。
两种选择:
不使用
xargs
:直接从with调用jq
路径名作为位置参数。读取找到的路径名,并将它们作为表达式中的数组访问。对于每个路径名,创建一个 JSON 对象。find
-exec
--args
$ARGS.positional[]
jq
使用
xargs
:使用-print0
withfind
和-0
withxargs
将找到的路径名从find
to安全传递xargs
。该jq
表达式与上述相同,只是路径名之间传递的方式find
不同jq
。使用上述两种方法,
jq
将对找到的路径名进行编码,以便能够将它们表示为 JSON 字符串。要将行读取到您显示的一组对象中,您可以使用以下
jq
命令,该命令从其标准输入流中读取:JSON 不能在其字符串中直接表示任意文件路径(它们是非零的字节序列),这些字符串是 UTF-8 编码字符的序列。另请注意,除非您
find
使用-print0
.例如,文件路径可能是
$'/home/St\xc3\xa9phane\nChazelas/ISO-8859-1/R\xe9sum\xe9'
(这里使用ksh93
-style$'...'
表示法表示字节值),é
UTF-8 编码为Stéphane
,ISO-8859-1 编码为Résumé
.除非您使用某种编码,否则 JSON 无法表示该文件路径。这可能是例如 URI 编码:
另一种方法可能是将路径解释为好像它是 ISO-8859-1 编码的(或任何字节值都可以成为有效字符的任何单字节字符集¹):
jq
对进行 URI 编码有一些支持,但不能为 AFAIK 提供非 UTF-8 输入。AFAIK,它也不支持编码转换。在 GNU 系统上,对于文件路径被认为是 ISO-8859-1 编码的第二种方法,您可以执行以下操作:
在我们上面的例子中给出了:
¹ 尽管 iso-8859-1 特别是一个明显的选择,因为它的代码点与 Unicode 的代码点匹配。因此,例如,如果您的 json 字符串包含 U+00E9 字符,您就知道它对应于 0xE9 字节。您可以添加
-a
选项以jq
将非 ASCII 字符表示为\uXXXX
。