【问题标题】:awk Extract Text Nth Occurrence Square Brackets (Containing Line Break In File Text)awk 提取文本第 N 次出现方括号(包含文件文本中的换行符)
【发布时间】:2021-03-17 13:40:37
【问题描述】:

我有 0.txt 和 1.txt 文件。 0.txt文件中内容如下图:

[{A,B,C},{D,E,F}][{G,H,I}]

1.txt文件内容如下图:

[{A,B,C},{D,E,F}]
[{G,H,I}]

也就是0.txt和1.txt的区别在于1.txt文件中有一个换行符。

我希望能够使用 @ 提取 NTH OCCURRENCE'['']' 之间的所有文本987654324@ (Extract the text between the nth occurrence of square brackets),用于 1.txt 文件中显示的文本格式。

所以我的n=2对应的愿望就是2.txt如下图:

{G,H,I}

为此,起初,我能够在没有换行符的情况下仅对文本格式执行此操作,如 0.txt 所示。

我需要知道如何提取 '['']' 之间的文本,当出现 1.txt 中所示的换行符时强>。

awk -F'[][]' -v n=2 '{ print $(2*n) }' 1.txt > 2.txt 的输出已经是 0.txt 的所有内容(方括号除外),而不仅仅是{G,H,I}。即2.txt内容如下:

{A,B,C},{D,E,F}
{G,H,I}

编辑更新 01:

考虑到第三次出现,即[{J, K, L}],解决方案必须对第三个输入文件具有以下相同的效果。所以预期的退出应该是{J, K, L}

[{A,B,C},{D,E,F}]
[{G,H,I}]
[{J,K,L}]

对于第 n 次出现 [{x, y, z, ..}] 的所有目的(尊重 [] 中没有文本的条件,并且没有空行)给出的任何解决方案都应该准确解压到输出文件{x, y, z, ..}

【问题讨论】:

  • 感谢您的努力和好帖子(继续努力),能否请您在您的问题中也发布预期输出的示例,更清楚一点,谢谢。
  • -F'[][]' 实际上在[] 之间找不到文本。例如awk -F'[][]' -v n=1 '{ print $(n*2) }' <<< '[abc' 将打印 abc

标签: regex awk


【解决方案1】:

如何用给定的记录号提取[]之间的文本

你可以试试这个gnu-awk 命令,不管括号对之间是否存在换行符,它都可以工作

awk -v n=2 -v RS='\\[[^]]*]' 'RT && NR == n {print substr(RT, 2, length(RT)-2)}' file

{G,H,I}

由于我们使用的是[...] 的自定义RS,因此无论第二对[...] 是在第一行还是第二行,它都会打印正确的记录。

【讨论】:

  • awk -v n=3 -v RS='\\[[^]]*]' 'RT && NR == n {print substr(RT, 2, length(RT)-2)}' <<< '[{A,B,C},{D,E,F}][{G,H,I}][aaa]' 将打印aaa
  • 抱歉,我发布了 Ed Morton 解决方案。
【解决方案2】:

使用 GNU awk 进行 FPAT:

$ awk -v FPAT='[^][\n]+' -v RS='^$' -v n=2 '{print $n}' 0.txt
{G,H,I}

$ awk -v FPAT='[^][\n]+' -v RS='^$' -v n=2 '{print $n}' 1.txt
{G,H,I}

使用任何 awk 并假设您在输入中没有任何空行:

$ awk -v RS= -F '][[:space:]]*[[]|^[[]|]$' -v n=2 '{print $(n+1)}' 0.txt
{G,H,I}

$ awk -v RS= -F '][[:space:]]*[[]|^[[]|]$' -v n=2 '{print $(n+1)}' 1.txt
{G,H,I}

【讨论】:

  • 第三次出现这种情况没有奏效。
  • 没有看到失败的输入并且只是“这不起作用”作为症状对不起,但我不知道如何调试它。我只能告诉您,它适用于您在问题中提供的示例输入/输出,并且适用于任何类似的输入。
  • 我正在使用awk -v FPAT='[^][\n]+' -v RS='^$' -v n=3 '{print $2}' 0.txt,其中 0.txt 是 [{A,B,C},{D,E,F}] \n [{G,H,I}] \n [{J,K,L}](其中 \n 是换行符,没有行空白)但给定输出 {G,H,I}
  • awk -v RS= -F '][[:space:]]*[[]|^[[]|]$' -v n=3 '{print $(n+1)}' 0.txt 它适用于 n=3。
  • @YaacovNNNNM 在您正在打印的 gawk 脚本中 $2,而不是 $n。当我第一次发布脚本时,它是这样做的,但我很快就修复了它。
【解决方案3】:

这是另一种方法,假设您的输入在[] 分隔符之外没有任何非换行符。这适用于任何awk

$ tr '[]' '\n' <ip.txt | awk -v RS= -v ORS= 'NR==2'
{G,H,I}

tr 命令会将所有[] 字符替换为换行符。 awk 命令使用 2 个或更多连续换行符作为记录分隔符。输入开头的任何多余的换行符都将被忽略。因此,您现在只需使用记录号即可获得所需的输出。

【讨论】:

    【解决方案4】:

    如果您使用grep 预处理数据,则提取变得微不足道,例如:

    n=3
    <0.txt grep -oE '\{[^}]+\}' | sed -n ${n}p
    <1.txt grep -oE '\{[^}]+\}' | sed -n ${n}p
    

    输出:

    {G,H,I}
    {G,H,I}
    

    编辑 - OP 要求的变化

    如果您想要的是方括号的内容,那么对此解决方案的微小更改仍然有效,例如:

    n=3
    <new.txt grep -oE '\[[^]]+\]' | tr -d '[]' | sed -n ${n}p
    

    输出:

    {J,K,L}
    

    【讨论】:

    • 我正在将您的脚本用作 file.sh,其中 0.txt 是 [{A,B,C},{D,E,F}] \n [{G,H,I}] \n [{J,K,L}](其中 \n 是换行符,没有行空白)但在运行文件时给出了输出 {G,H,I}。 sh 而不是 {J,K,L}。注意:我对 n=3 说你的脚本怎么样。
    • @YaacovNNNNM:将n=3 更改为n=4?
    • 我最终没有这样做,您的解决方案适用于 n=4,抱歉 :)
    • @YaacovNNNNM:如果您在正则表达式中使用方括号,您仍然可以使用此解决方案,请参阅编辑。
    猜你喜欢
    • 2019-02-26
    • 1970-01-01
    • 2013-08-14
    • 2019-05-20
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多