【问题标题】:Using Unix Tools to Extract String Values使用 Unix 工具提取字符串值
【发布时间】:2010-12-17 02:50:43
【问题描述】:

我编写了一个小的 Perl 脚本来从给定键名的 JSON 格式字符串中提取所有值(如下所示)。因此,如果我将 Perl 脚本的命令行开关设置为 id,那么它将从下面的 JSON 示例返回 1,2 和 stringVal。这个脚本可以完成这项工作,但我想看看其他人如何使用其他 unix 风格的工具(如 awk、sed 或 perl 本身)来解决同样的问题。谢谢

{
   "id":"1",
   "key2":"blah"
},
{
   "id":"2",
   "key9":"more blah"
},
{
   "id":"stringVal",
   "anotherKey":"even more blah"
}

提取 JSON 值的 perl 脚本摘录:

my @values;
while(<STDIN>) {
    chomp;
    s/\s+//g; # Remove spaces
    s/"//g; # Remove quotes
    push @values, /$opt_s:([\w]+),?/g; # $opt_s is a command line switch for the key to find
}

print join("\n",@values);

【问题讨论】:

    标签: linux perl json unix awk


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      我强烈建议使用JSON 模块。它将在一个函数中解析您的 json 输入(并返回)。它还提供 OOP 接口。

      【讨论】:

        【解决方案3】:

        呆呆

        gawk 'BEGIN{
         FS=":"
         printf "Enter key name: "
         getline key < "-"
        }
        $0~key{
          k=$2; getline ; v = $2
          gsub("\"","",k)
          gsub("\"","",v)
          print k,v
        }' file
        

        输出

        $ ./shell.sh
        Enter key name: id
        1, blah
        2, more blah
        stringVal, even more blah
        

        如果你只想要 id 值,

        $ key="id"
        $ awk -vkey=$key -F":" '$0~key{gsub("\042|,","",$2);print $2}' file
        1
        2
        stringVal
        

        【讨论】:

        • 第二个很好的例子。 gsub("\042|,","",$2) 究竟做了什么?
        • 它说对双引号和逗号进行全局替换。请检查您的 ascii 表以了解 \042 的含义。
        【解决方案4】:

        这是完成任务的一个非常粗略的 Awk 脚本:

        awk -v k=id -F: '/{|}/{next}{gsub(/^ +|,$/,"");gsub(/"/,"");if($1==k)print $2}' data
        
        • -F: 指定 ':' 作为字段分隔符
        • -v k=id 设置您的密钥 正在搜索。
        • 包含“{”的行 或“}”被跳过。
        • 第一个 gsub 摆脱前导空格和 尾随逗号。
        • 第二个 gsub 得到 摆脱双引号。
        • 最后,如果 k 匹配 $1,打印 $2。

        data 是包含您的 JSON 的文件

        【讨论】:

        • 很好的解决方案。我希望得到一个纯粹的 awk 答案,因为我正在尝试使用 awk 进行改进。谢谢。
        • @steve,注意结果和你的perl结果不同。
        • 请注意:只要文件中有空行或格式稍有变化,就会失败
        • 我在stackoverflow.com/a/10468771/272427指出了一个强大的纯awk解决方案
        【解决方案5】:

        sed(前提是文件格式如上,每行不超过一个条目):

        KEY=id;cat file|sed -n "s/^[[:space:]]*\"$KEY\":\"//p"|sed 's/".*$//'
        

        【讨论】:

        • 当然没必要,只是源文件名靠近脚本的开头,而不是埋在一行一行的中间
        【解决方案6】:

        当有库可以为您解析字符串时,您为什么要自己解析? json.org 拥有几乎所有你能想到的语言的 JSON 解析和编码库(可能还有一些你没有想到的语言)。在 Perl 中:

        use strict;
        use warnings;
        use JSON qw(from_json to_json);
        
        # enable slurp mode
        local $/;
        
        my $string = <DATA>;
        my $data = from_json($string);
        
        use Data::Dumper;
        print "the data was parsed as: " . Dumper($data);
        
        __DATA__
        [
            {
               "id":"1",
               "key2":"blah"
            },
            {
               "id":"2",
               "key9":"more blah"
            },
            {
               "id":"stringVal",
               "anotherKey":"even more blah"
            }
        ]
        

        ..产生输出(我在数据周围添加了一个顶级数组,因此它将被解析为一个对象):

        the data was parsed as: $VAR1 = [
                  {
                    'key2' => 'blah',
                    'id' => '1'
                  },
                  {
                    'key9' => 'more blah',
                    'id' => '2'
                  },
                  {
                    'anotherKey' => 'even more blah',
                    'id' => 'stringVal'
                  }
                ];
        

        【讨论】:

          【解决方案7】:

          如果您不介意看到引号和冒号字符,我会简单地使用grep

          grep id file.json

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-04-03
            • 2015-11-29
            • 2016-08-25
            • 1970-01-01
            • 1970-01-01
            • 2016-08-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多