如何使用 sed/awk 提取两个模式之间的文本

2024-02-18

我知道这个问题已经被问了 1000 次了,但是我读了很多类似的问题,但仍然没有找到正确的方法来做到这一点。我需要从如下所示的行中提取一个数字:

{"version":"4.9.123M","info":{"version":[2034.2],"description":""},"status":"OK"}

预期输出:

2034.2

该版本号并不总是相同,但该行的其余部分应该相同。

我尝试过使用 sed 但我对此很陌生并且失败了:

 sed -e 's/version":[\(.*\),"description/\1/'

output:

sed: -e expression #1, char 35: unterminated `s' command

我认为问题在于该行中涉及太多特殊字符,并且我没有写好命令。


由于它是 JSON,因此应使用 JSON 感知工具来处理它。例如,如果您更喜欢 awk,可以使用 GNU awk 的 JSON 扩展。这是一个小操作方法。

首先下载并编译适当版本的 GNU awk、Gawkextlib 和gawk-json http://gawkextlib.sourceforge.net/json/json.html。其实这很简单,只需./configure and make。然后,编写一些代码:

awk '
@load "json"                                 # enable json extension
{
   lines=lines $0                            # read json file records and buffer to var lines
   if(json_fromJSON(lines,data)==1) {        # once the json is complete
       for(i in data["info"]["version"])     # that seems to be an array so all elements
           print data["info"]["version"][i]  # are outputed
       lines=""                              # once done with the first json object
   }                                         # reset the var for more lines
}' file

这次输出:

2034.2

多解释一下:

JSON 文件结构可以从一行到多行不等,例如:

{"version":"4.9.123M","info":{"version":[2034.2],"description":""},"status":"OK"}

or:

{
  "version": "4.9.123M",
  "info": {
    "version": [
      2034.2
    ],
    "description": ""
  },
  "status": "OK"
}

所以我们需要缓冲 JSON 行lines=lines $0直到变量中有一个完整的有效对象lines。我们使用扩展函数json_fromJSON()以确定有效性if(json_fromJSON(lines,data)==1)。验证时,对象被解开并存储到数组中data。对于这个特定对象,数组的结构是:

data["version"]="4.9.123M"
data["info"]["version"][1]="2034.2"
data["info"]["description"]=""
data["status"]="OK"

我们可以使用这个递归数组扫描函数检查对象并产生它的一些输出:

awk '
@load "json"
function scan(a,p,    q) {           # a is array, p path to it, q is qnd *
    if(isarray(a))
        for(i in a) {
            q=p (p==""?"":"->") i
            scan(a[i],q)
        }
    else
        print p ":" a
}
{
   lines=lines $0
   if(json_fromJSON(lines,data)==1)
       scan(data)                    #
}' file.json

Output:

status:OK
version:4.9.123M
info->version->1:2034.2
info->description:

*)又快又脏

以下是如何从数组输出 JSON 的简短示例:https://stackoverflow.com/a/58109715/4162356 https://stackoverflow.com/a/58109715/4162356

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 sed/awk 提取两个模式之间的文本 的相关文章

  • 查找并删除超过 x 天的文件或文件夹

    我想删除超过 7 天的文件和文件夹 所以我尝试了 17 07 14 email protected cdn cgi l email protection find tmp mindepth 1 maxdepth 1 ctime 7 exec
  • sed - 删除行尾的句点

    我正在尝试删除文本文件中行尾的句点 有些行末尾有句点 有些则没有 cat textfile sometexthere 123 22 no period moretext with period lt remove this period n
  • 在 Shell 中提取匹配模式后的字符串

    如何提取 Shell 脚本中匹配模式后面的任何字符串 我知道 Perl 脚本中的此功能 但不知道 Shell 脚本中的功能 以下是示例 subject 01 这是一个示例主题 可能会有所不同 我必须提取 Subject 01 后面的任何字符
  • 将变量插入 sh 脚本命令[重复]

    这个问题在这里已经有答案了 bin sh f set proj dir OutputDir for projname in lib proj1 proj2 do mv scripts projname BYTECODE proj dir s
  • Bash 的源命令无法处理从互联网上卷曲的文件

    我正在尝试使用curl从互联网获取脚本文件 如下所示 source lt curl url echo done 我看到的是 完成 得到了回响before卷曲甚至开始下载文件 这是实际的命令和输出 bash 3 2 source lt cur
  • 在 Django shell 会话期间获取 SQL 查询计数

    有没有办法打印 Django ORM 在 Django shell 会话期间执行的原始 SQL 查询的数量 Django 调试工具栏已经提供了此类信息 例如 5 QUERIES in 5 83MS但如何从 shell 中获取它并不明显 您可
  • tcsh 脚本 if 语句

    我需要循环遍历一堆不同的场景 变量场景 但无法弄清楚如何在 tcsh shell 脚本中使用 if 语句 收到错误 if 表达式语法 有人可以告诉我我有什么问题吗 简化代码如下 谢谢 bin tcsh f set val 0 foreach
  • 打印文件的每第 n 列

    我有一个相当大的文件 有 255 个逗号分隔的列 我只需要打印出每第三列 我正在尝试这样的事情 awk for i 0 i lt NF i 3 print i file 但这似乎不是解决方案 因为它只打印到一长列 有人可以帮忙吗 谢谢 这是
  • 使用 sed 将反斜杠替换为斜杠[重复]

    这个问题在这里已经有答案了 我需要更换 with 我有一个文件 其中包含 test test2 test3 test4 I tried VRS Ruta cat ruta lst sed s g sed s g output test te
  • 如何将命令输出作为多个参数传递给另一个命令

    我想将命令的每个输出作为多个参数传递给第二个命令 例如 grep pattern input returns file1 file2 file3 我想复制这些输出 例如 cp file1 file1 bac cp file2 file2 b
  • 如何将输出重定向到文件,如果文件不存在则不创建它?

    我需要将输出重定向到一个文件 gt 在 shell 中 但如果该文件尚不存在 则不应创建该文件 如何实现这一目标 我尝试创建文件的符号链接并重定向到符号链接 但不幸的是 如果文件尚不存在 无论如何都会创建文件 也许我需要重定向到一个单独的程
  • 如何在不使用 MacPorts 或 Fink 的情况下在 OS X Leopard 上安装 lxml?

    我过去曾多次尝试过此操作并遇到问题 有没有人有在没有 MacPorts 或 Fink 的情况下在 OS X 上安装 lxml 的方法 并且绝对有效 最好有完整的 1 2 3 步骤来下载和构建每个依赖项 感谢 Twitter 上的 jesse
  • “./somescript.sh”和“. ./somescript.sh”有什么区别

    今天我按照一些说明在 Linux 中安装软件 有一个需要首先运行的脚本 它设置一些环境变量 指令告诉我执行 setup sh 但是我执行时犯了一个错误 setup sh 所以环境没有设置 最后我注意到了这一点并继续进行 我想知道这两种调用脚
  • awk 每个文件后换行

    使用此脚本 每个字段都会根据当前文件的最长单词打印出来 但需要每个文件都有一个换行符 如何才能实现这一目标 awk BEGIN ORS n FNR NR a i 0 if length 0 gt length max max 0 l len
  • bash - 检查特定列中的单词,检查该行其他列中的值,将该行剪切并粘贴到新文本文件中

    我的文本文件包含约 20k 行 如下所示 file A ATOM 624 SC1 SER 288 54 730 23 870 56 950 1 00 0 00 ATOM 3199 NC3 POP 487 50 780 27 750 27 5
  • 如何迭代 Bash 中变量定义的数字范围?

    当范围由变量给出时 如何在 Bash 中迭代数字范围 我知道我可以做到这一点 在 Bash 中称为 序列表达式 文档 http www gnu org software bash manual bashref html Brace Expa
  • 使用 BASH 和 AWK 创建 HTML 表

    我在创建 html 表来显示文本文件中的统计信息时遇到问题 我确信有 100 种方法可以做得更好 但这里是 以下脚本中的注释显示了输出 bin bash function getapistats curl s http api exampl
  • 排除正则表达式匹配中的字符串,以进行 sed 处理

    我需要将其匹配为替代命令 whatever MATCH THIS whateverwhatever AND THIS whateverwhatever 我正在尝试 sed e s 1 g myfile 但这是急切的匹配 MATCH THIS
  • 在 shell 脚本中将脚本目录更改为用户的 homedir

    在我的 bash 脚本中 我需要将当前目录更改为用户的主目录 如果我想更改为用户的foo主目录 从命令行我可以执行以下操作 cd foo 效果很好 但是当我从script它告诉我 bar sh line 4 cd foo No such f
  • AWK 或 sed 方式粘贴非相邻行

    cat file aaa bbb ccc ddd eee jjj kkk lll mmm nnn ooo ppp 以下 AWK 命令会将 mmm 行粘贴到 ddd eee 行的末尾 有没有更简单的方法使用 AWK 或 sed 来做到这一点

随机推荐