【问题标题】:Awk to print a single next word followin a pattern matchawk 在模式匹配之后打印单个下一个单词
【发布时间】:2021-01-21 21:39:02
【问题描述】:

这个 Q 是在图案之后打印某些东西的主题的变体。

会有带有单词的输入行。有些行将匹配一个模式,其中该模式将是一个或多个由空格分隔的单词。该模式可能有一个需要遵守的前导/尾随空格。我需要在比赛后立即打印单词。

示例输入

The quick brown fox jumps over the lazy dog

Pattern : "brown fox "
Desired output : jumps

模式只会在一行中出现一次。模式后面总会有一个词。会有没有图案的线条。

awk 或 sed 会很好。

干杯。

编辑:

我没有正确地提出问题。模式和下一个单词之间会有一个或多个空格。这打破了安德烈的提议。

    % echo -e "The quick brown fox jumps over the lazy dog\n" | awk -F 'brown fox ' 'NF>1{ sub(/ .*/,"",$NF); print $NF }'
jumps
    % echo -e "The quick brown fox    jumps over the lazy dog\n" | awk -F 'brown fox ' 'NF>1{ sub(/ .*/,"",$NF); print $NF }'

【问题讨论】:

  • 请阅读stackoverflow.com/questions/65621325/… 以了解其重要性,然后在您的问题中出现的任何地方将“模式”一词替换为“正则表达式”或“字符串”,并添加有关部分匹配应该如何的信息已处理(例如,own fox 是否与 brown fox 匹配?)。一旦您这样做了,我们就可以帮助您为您的问题找到正确的解决方案。

标签: awk


【解决方案1】:

这可行,因为所需的单词后面跟着一个 空格

$ echo -e "The quick brown fox jumps over the lazy dog\n" > file

$ awk -F 'brown fox ' 'NF>1{ sub(/ .*/,"",$NF); print $NF }' file
jumps

编辑: 如果有更多的空间使用这个:

$ awk -F 'brown fox' 'NF>1{ sub(/^ */,"",$NF);
                            sub(/ .*/,"",$NF); print $NF }' file

【讨论】:

    【解决方案2】:

    免责声明:此解决方案假定如果未找到模式(会有没有模式的行。)打印空行是合适的,如果这不成立,则完全忽略此答案。

    我将使用AWK 进行以下方式,让file.txt 内容为

    The quick brown fox jumps over the lazy dog
    No animals in this line
    The quick brown fox   jumps over the lazy dog
    

    然后

    awk 'BEGIN{FS="brown fox  *"}{sub(/ .*/,"",$2);print $2}' file.txt
    

    输出

    jumps
    
    jumps
    

    解释:我将字段分隔符FS 设置为"brown fox ",后跟任意数量的空格。之后的内容将出现在第 2 列,我从第 2 列丢弃第一个空格(包括所述空格)之后的任何内容,然后打印该列。如果没有匹配,第二列是空的,这些操作会导致空行。

    【讨论】:

      【解决方案3】:

      使用 GNU grep:

      $ grep -oP '(?<=brown fox )(\w+)' file
      jumps
      

      如果你在比赛结束后有超过 1 个空格:

      $ echo 'The quick brown fox     jumps over the lazy dog' | grep -oP '(?<=\bbrown fox\b)\s+\K(\w+)'
      jumps
      

      Perl,使用相同的正则表达式:

      $ perl -lnE 'print $1 if /(?<=\bbrown fox )(\w+)/' file
      

      或者,如果您有多个空格:

      $ perl -lnE 'print $1 if /(?<=brown fox)\s+(\w+)/' file
      

      (如 cmets 中所述,GNU grep 和 Perl 正则表达式都可以是 \bbrown\h+fox\h+\K\w+,其优点是支持 brownfox 之间的多个空格)

      使用 awk,您可以对字符串进行拆分并拆分结果(这适用于多个空格):

      pat='brown fox'
      awk -v pat="$pat" 'index($0, pat){
                  split($0,arr, pat)
                  split(arr[2], arr2)
                  print arr2[1]}' file
      

      【讨论】:

      • 不幸的是,模式和捕获词之间有多个空格,这被破坏了。
      • 轻松修复。已编辑。
      • 我只测试了grep版本。没关系。
      • (grep 和 perl 的 perl 兼容模式可以是 \bbrown\h+fox\h+\K\w+,无需后视)
      【解决方案4】:

      使用 GNU awk,您还可以使用具有函数 match 的捕获组。

      \ybrown\s+fox\s+(\w+)
      
      • \y一个字边界
      • brown\s+ 匹配棕色和 1+ 个空白字符
      • fox\s+ 匹配 fox 和 1+ 个空白字符
      • (\w+)组 1 中捕获 1+ 个单词字符

      在awk中,使用arr[1]获取组1的值

      例子

      echo "The quick brown fox jumps over the lazy dog" |
      awk 'match($0,/\ybrown\s+fox\s+(\w+)/, arr) {print arr[1]}'
      

      输出

      jumps
      

      查看bash demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-14
        • 1970-01-01
        • 2017-10-14
        • 1970-01-01
        • 1970-01-01
        • 2014-12-13
        • 1970-01-01
        相关资源
        最近更新 更多