是否可以通过python将普通文本转换为JSON格式?

时间:2014-04-18 07:36:12

标签: python json

我已经开始对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还是什么? 我必须遵循哪些可能的先决条件或步骤?

任何建议都会非常值得注意。

谢谢,

2 个答案:

答案 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部分)。