我已经开始对python有了很好的掌握,同时我遇到了JSON文章。由此,我想要结合这两个概念。 目前我有一个小脚本(python脚本),可以触发一些内置命令并将输出存储在一个文件中。
这是代码段
import subprocess, os
output_file_object = open("output.txt", "wb")
command = ['/bin/ls', '-l']
command_output = subprocess.check_output(command)
output_file_object.write(command_output)
output_file_object.close()
print 'Done'
创建文件并包含输出。
有什么办法可以用JSON格式保存这个输出吗? 有API还是什么? 我必须遵循哪些可能的先决条件或步骤?
任何建议都会非常值得注意。
谢谢,
答案 0 :(得分:2)
我很乐意回答我自己的问题,我希望这能帮助有需要的人。
我使用了名为Gelatin(https://github.com/knipknap/Gelatin/wiki)的API。你必须自己设置明胶,因为我没有在这里解释设置过程。 起初它看起来像一个繁琐的任务,但你得到的输出是非常值得的。内部明胶使用python的json模块。
为了获得完美的输出,你必须使用明胶的语法。简单来说,我可以说"语法"明胶就像"功能"任何语言。
"文法"完全基于正则表达式(正则表达式)。是!你必须在这里了解一下regex。它将使语法定义的任务变得容易。
让我们回到我的问题的解决方案。
我有一个文本文件,它是ls
命令的输出。文件内容如下:
total 20
-rw-rw-r-- 1 shiv shiv 0 Apr 25 10:42 output.txt
-rw-r--r-- 1 shiv shiv 296 Apr 25 10:41 temp-script.py
现在让我们开始定义语法。
您必须根据需要定义新的语法文件。 这是我为"输出命令"
创建的语法文件define nl /[\r\n]/
define ws /\s+/
define fieldname /[\w ]+/
define value /[^\r\n]+/
define field_end /[\r\n,] */
define colon_end /:/
define permission /[dl-][r-][w-][x-][r-][w-][x-][r-][w-][x-]/
define digit /[0-9]+/
grammar content:
match permission ws value field_end:
out.open('content')
out.add_attribute('.', 'content-stuff', '$2')
out.add_attribute('.', 'permission', '$0')
match nl:
do.return()
do.return()
grammar input:
match 'total' ws digit nl:
out.open('tag1')
content()
在顶部是正则表达式,我想这是自我解释的 (重要) - "语法输入"是切入点。明胶解析器将从此处开始执行。它相当于" main"在C和C ++中。
定义语法文件很有趣。你必须告诉明胶解析器的所有内容。
在"语法输入"中,我告诉解析器"匹配"以" total"开头的东西接着是空格(ws),然后是"数字"最后是NewLine(nl)。 找到匹配项后,它将打开一个名为" tag1"的json标签。 (您可以根据自己的方便来命名)。
打开标签后,下一行是调用另一个名为" content" (这也可以是任何名字)
现在"语法内容"这将找到以"许可"开头的行。这只是权限的正则表达式。 一旦完整的行匹配即(权限ws值field_end), 它将执行out.add_attribute函数(' out'是一个内置对象)。
(注意 - '许可'是0美元,' ws'是1美元,'价值'是2美元等等..
out.add_attribute('.', 'content-stuff', '$2')
请记住我们在" tag1",
'.' means current tag
'content-stuff' -- Json "key"
'$2' -- JSON "value"
out.open(' content') - 当你想创建一个数组时,基本上就会使用它。
定义语法时,是执行命令的时间。
gel -s< - syntax-filename.gel - > -f json< - input-filename - >
gel -s syntax.gel -f json output.txt
{
"tag1": {
"content": [
{
"@content-stuff": "1 shiv shiv 0 Apr 25 10:42 output.txt",
"@permission": "-rw-rw-r--"
},
{
"@content-stuff": "1 shiv shiv 296 Apr 25 10:41 temp-script.py",
"@permission": "-rw-r--r--"
}
]
}
}
这肯定需要一些时间,但我想分享一些愚蠢(但很搞笑)的事情,你在定义语法文件时必须小心谨慎,否则你会疯了。
-Make sure there are no spaces left at the end of line(right hand side), especially while defining "grammar" (at the end after ':') [in syntax file]
-take care about using spaces and NO tabs. [in syntx file]
TAB相当于四个SPACES,但您必须手动提供四个SPACES,单个选项卡将导致语法错误。
-the "match" statement do not accepts spaces ie (as explained below)
`-match 'Defines Permissions:' -->will NOT work`
`-match 'Defines' ws 'Permissions:' --> will WORK`
答案 1 :(得分:1)
从ls
命令检索输出后:
>>> out = subprocess.check_output(command)
你只需要提取你想要的东西,例如:
>>> # Get the lines, remove the first and the last ones, and split into columns
>>> out = [o.split() for o in out.split('\n')[1:-1]]
然后你只需要使用json模块:
>>> import json
>>> json_out = json.dumps(out)
>>> with open('output.json', 'w') as f:
>>> f.write(json_out)
显然你必须做得比我在这里做的更好,因为将ls拆分成列并不能输出真正可读的JSON(你得到大量的字符串,日期被分成3部分)。