破译bash扩展正则表达式

时间:2014-12-03 11:52:53

标签: regex bash

我有一个输入数据,它遵循以下格式(全部是1行):

  

{“auth”:“15a63c4:e66189ba”,“createdAt”:“2013-05-12T00:00:01-08:00”,   “payload”:{“itemId”“:”15607“,”marker“:240},”refId“:”47c7e2f6“,   “sessionID”:“82ada851-0b3c-4e9d-b8cf-0f0a2ebed278”,“type”:“Play”,   “user”:22700996,“userAgent”:“Mozilla / 4.0(兼容; MSIE 7.0;   Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)“}

我有一个带有古怪正则表达式的grep命令:

grep -Eo "\"$1\": [^,]+" | cut -d: -f2- | tr -d '" '

我怀疑(不完全确定并且很难检查)它会返回:

  

“type”:“Play”

你可以向我解释(分解并解释)这个命令和正则表达式的地狱吗?

我花了大约40分钟使用所有的互联网参考资料,但是没有更接近理解grep究竟是什么:(

编辑:脚本的输入参数为“type”,因此$ 1代表“type”

3 个答案:

答案 0 :(得分:1)

这不仅仅是一个正则表达式,它是一个包含变量插值的字符串。无论在Bash中设置的$1是什么,都将包含在正则表达式中。但显然,目的是在type中使用$1之类的内容来调用它,并从JSONish片段中提取type(即Play)的值。

xtract () {
    grep -Eo "\"$1\": [^,]+" | cut -d: -f2- | tr -d '" '
}

xtract "type" <<'HERE'
{"auth": "15a63c4:e66189ba", "createdAt": "2013-05-12T00:00:01-08:00",
 "payload": {"itemId"": "15607", "marker": 240}, "refId": "47c7e2f6",
 "sessionID": "82ada851-0b3c-4e9d-b8cf-0f0a2ebed278", "type": "Play",
 "user": 22700996, "userAgent": "Mozilla/4.0 (compatible; etc etc)"}
HERE

输出:

Play

所以你看,你可以将一个键作为参数传递给函数xtract,并且它将提取该键的值(假设输入结构合理,这里是真的 1 但是在宏观计划中失败的一个秘诀。)

1 嗯,不是真的;密钥后itemId有两个双引号。   因此,使用此特定示例输入,您不能xtract itemId(但如果您知道问题是什么,则可以作弊并xtract 'itemId"'!)

正则表达式在双引号中查找键,后跟任何不是逗号的键。它将在冒号后提取所有内容,并从中删除任何双引号和空格。

更正确的解决方案不会破坏包含双引号内的逗号或值中的空格的值;如果输入是正确的JSON,那么专用的JSON工具(例如jq)将比使用正则表达式的ad-hoc解析器更受欢迎。

$ jq -r '.type' <<'HERE'
{"auth": "15a63c4:e66189ba", "createdAt": "2013-05-12T00:00:01-08:00",
 "payload": {"itemId": "15607", "marker": 240}, "refId": "47c7e2f6",
 "sessionID": "82ada851-0b3c-4e9d-b8cf-0f0a2ebed278", "type": "Play",
 "user": 22700996, "userAgent": "Mozilla/4.0 (compatible; etc etc)"}
HERE
Play

(再次注意,这需要格式正确的JSON输入。)

答案 1 :(得分:1)

让我们分解管道:

grep -Eo "\"$1\": [^,]+"

这会在输入文本中搜索文字双引号(使用反斜杠转义),后跟$1的值(即传递给包含此命令的脚本/函数的第一个参数),另一个文字双引号,一个文字空间,然后是一个或多个不是逗号的字符。如果$1type,则结果为"type": "Play"

cut -d: -f2-

这使用冒号作为cut的分隔符,并打印出输入的第二个和后续字段。继续这个例子,结果将是"Play"(注意空间仍在那里)。

tr -d '" '

-d的{​​{1}}选项实际上意味着&#34;删除&#34; - 所以删除所有双引号和空格。结果现在是tr

意图似乎是您将密钥作为脚本/函数的第一个参数传递,并返回相应的值。

答案 2 :(得分:0)

  • grep -Eo "\"$1\": [^,]+"
    这里假设$ 1为类型。此命令将为您提供来自&#34;字符串的字符串,直到它与第一个逗号匹配。所以这里你的输出是

    "type": "Play"
    
  • cut -d:-f2-
    输出grep命令输入到cut命令,该命令将文件拆分为:(冒号)作为分隔符,并向前输出字段2将输出的任何字符串

    "Play"
    
  • tr -d&#39;&#34; &#39;
    此命令将从cut命令获取输入,并将从cut命令中收到的字符串中删除所有空格和双引号。所以输出将是

    Play