将 bash 'ls' 输出转换为 JSON 数组



是否可以使用 bash 脚本将ls的输出格式化为 json 数组?要成为有效的 json,dirs 和文件的所有名称都需要用双引号括起来,用逗号分隔,并且整个内容需要括在方括号中。即转换:

jeroen@jeroen-ubuntu:~/Desktop$ ls
foo.txt bar baz

[ "foo.txt", "bar", "baz" ]

编辑:我非常喜欢在所有Linux服务器上工作的东西;因此,宁愿不依赖python,而是有一个纯粹的bash解决方案。

如果您知道没有文件名包含换行符,请使用 jq:

ls | jq -R -s -c 'split("n")[:-1]'

对 jq 标志的简短解释:

  • -R将输入视为字符串而不是 JSON
  • -s将所有行连接到一个数组中
  • -c产生紧凑的输出
  • [:-1]删除输出数组中的最后一个空字符串

这需要 jq 的 1.4 或更高版本。如果它不适合您,请尝试以下操作:

ls | jq -R '[.]' | jq -s -c 'add'

是的,但是极端情况和 Unicode 处理会让你上墙。最好委托给本机支持它的脚本语言。

$ ls
あ  a  "a"  à  a b  私
$ python -c 'import os, json; print json.dumps(os.listdir("."))'
["u00e0", ""a"", "u79c1", "a b", "u3042", "a"]

你好,你可以用sed和awk来做到这一点:

ls | awk ' BEGIN { ORS = ""; print "["; } { print "/@"$0"/@"; } END { print "]"; }' | sed "s^"^\\"^g;s^/@/@^", "^g;s^/@^"^g"

编辑:更新以解决"和空格的问题。我使用/@作为"的替换模式,因为/不是文件名的有效字符。

使用

perl 作为编码器;它保证没有错误,无处不在,并且使用管道,它仍然相当干净:

ls | perl -e 'use JSON; @in=grep(s/n$//, <>); print encode_json(@in)."n";'

大多数Linux机器已经有了python。 您所要做的就是:

python -c 'import os, json; print json.dumps(os.listdir("/yourdirectory"))'

这是针对 . 目录的,您可以添加任何路径。

这是一个 bash 线

echo '[' ; ls --format=commas|sed -e 's/^/"/'|sed -e 's/,$/",/'|sed -e 's/([^,])$/1"]/'|sed -e 's/, /", "/g'

无法正确处理文件名中的"或一些逗号。 此外,如果ls在文件名之间放置换行符,那么也会这样做。

应该

很容易。

$ cat ls2json.bash
#!/bin/bash
echo -n '['
for FILE in $(ls | sed -e 's/"/\"/g')
do
echo -n "${FILE}",
done
echo -en \b']'

然后运行:

$ ./ls2json.bash > json.out

但是Python会更容易

import os
directory = '/some/dir'
ls = os.listdir(directory)
dirstring = str(ls)
print dirstring.replace("'",'"')

我也在寻找一种将 Linux 文件夹/文件树输出到某个 JSON 或 XML 文件的方法。为什么不使用这个简单的终端命令:

$ tree --dirsfirst --noreport -n -X -i -s -D -f -o my.xml

因此,只需使用 Linux 树命令,并配置您自己的参数。在这里-X给出了 XML 输出!对我来说,没关系,我想有一些脚本可以将XML转换为JSON。

注意:我认为这涵盖了相同的问题。

这是一个不依赖于 jq 的优雅单行解决方案:

echo '[ "'"$(echo "$list" | sed ':a;N;$!ba;s/n/", "/g')"'" ]'

$list 这里是一个换行符分隔的字符串。

使用 gnu 列(即在 OSX 上不起作用)

ls -ldG * --time-style=long-iso | column -t -n "$PWD" -N mod,links,user,size,date,time,name -J

输出:

{
   "/home/pouet": [
      {"mod":"-rwxr-xr-x", "links":"1", "user":"pouet", "size":"21978", "date":"2022-08-12", "time":"11:47", "name":"file1"},
      {"mod":"-rw-r--r--", "links":"1", "user":"pouet", "size":"2634", "date":"2022-06-20", "time":"11:14", "name":"file2"}
   ]
}

对于使用 jq 的更简单的解决方案:

ls | jq --raw-input | jq --slurp --compact-output

或者,如果您更喜欢较短的语法:

ls | jq -R | jq -s -c

从手册

https://jqlang.github.io/jq/manual/#Invokingjq

--raw-input / -R

不要将输入解析为 JSON。相反,每行文本都作为字符串传递到筛选器。如果与 --slurp 结合使用,则整个输入将作为单个长字符串传递到过滤器。

--slurp / -s

不要为输入中的每个 JSON 对象运行筛选器,而是将整个输入流读入一个大型数组,并且只运行筛选器一次。

--compact-output / -c

默认情况下,jq 漂亮打印 JSON 输出。使用此选项将把每个 JSON 对象放在一行上,从而产生更紧凑的输出。

个人而言,我会编写运行命令 ls 的脚本,将输出发送到您选择的文件,同时解析输出以将其格式化为有效的 JSON 格式。

我相信一个简单的 Bash 文件可以完成这项工作。

你不能

使用这样的python脚本吗?

myOutput = subprocess.check_output["ls"]
output = ["+str(e)+" for e in myOutput]
return output

我没有检查它是否有效,但你可以在这里找到规范

不要使用

bash,使用脚本语言。未经测试的perl示例:

use JSON;
my @ls_output = `ls`; ## probably better to use a perl module to do this, like DirHandle
print encode_json( @ls_output );

最新更新