【问题标题】:Only using sed to select mid portion on a string仅使用 sed 选择字符串的中间部分
【发布时间】:2021-12-13 07:34:10
【问题描述】:

我的文件包含这样的文本

4539 甲板 AAA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 甲板ABC
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 甲板ABA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 甲板ABD
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999

我想从中提取一个选定的端口。所以输出必须是这样的。没有前后空格制表符

AAA 
ABC 
ABA
ABD

我使用了这个,但它在文本之后选择了整行。有没有办法使用only sed。对任何其他解决方案不感兴趣

sed "s/.*DECK[[:blank:]](.[A-Z])*/\1/"

【问题讨论】:

    标签: logging sed


    【解决方案1】:

    第一种解决方案: 使用您展示的示例,尝试在此处使用以下sed。使用-E-n 选项分别启用ERE 和停止打印行。然后匹配从开始到直到甲板的所有内容,然后是空格,然后创建第一个反向引用以在行尾有大写字母;然后在替换部分用第一个反向引用值替换它。

    sed -E -n 's/.*DECK[[:space:]]+([A-Z]+$)/\1/p' Input_file
    


    第二个解决方案: 使用awk,您可以尝试使用所示示例编写和测试以下程序。简单的解释是,使用awkmatch 函数匹配正则表达式DECK [A-Z]+ 查找sting DECK,后跟空格,后跟大写字母,然后只打印所需的输出。

    awk 'match($0,/DECK [A-Z]+/){print substr($0,RSTART+5,RLENGTH-5)}' Input_file
    


    第三种解决方案: 使用 GNU grep 尝试一次。首先使用-oP 选项精确匹配匹配的正则表达式并分别启用ERE。匹配所有内容直到 DECK 空间和 \K 忘记它然后匹配大写字母并打印它们。

    grep -oP '.*DECK[[:space:]]*\K[A-Z]+'  Input_file
    

    【讨论】:

      【解决方案2】:

      你可以使用

      sed -n '/.*DECK[[:blank:]]*\([[:upper:]]*\).*/s//\1/p' 
      

      详情

      • n - 禁止默认行输出
      • /.*DECK[[:blank:]]*\([[:upper:]]*\).*/ - 零个或多个字符,DECK,然后匹配零个或多个水平空格,然后消耗零个或多个大写字母并放入第 1 组,然后匹配字符串的其余部分(此处为行)
      • s//\1/p - 上面模式中的匹配项(空模式告诉 sed 采用之前使用的那个)被替换为 Group 1 值,只有这个值是 printed。

      online demo

      #!/bin/bash
      s='4539 DECK AAA                      
      OO-99999999-99999999-99999999-99999999 -99999999-99999999   259800  
      259800   259800-99999999-99999999 4539 DECK ABC                      
      OO-99999999-99999999-99999999-99999999 -99999999-99999999   259800  
      259800   259800-99999999-99999999 4539 DECK ABA                      
      OO-99999999-99999999-99999999-99999999 -99999999-99999999   259800  
      259800   259800-99999999-99999999 4539 DECK ABD                      
      OO-99999999-99999999-99999999-99999999 -99999999-99999999   259800  
      259800   259800-99999999-99999999'
      sed -n '/.*DECK[[:blank:]]*\([A-Z]*\).*/s//\1/p' <<< "$s"
      

      输出:

      AAA
      ABC
      ABA
      ABD
      

      【讨论】:

      • 谢谢,这就是我想要的。我这样修改并使用它: sed '/.*DECK[[:blank:]]*([A-Z]*).*/s//\1/' inputfile
      猜你喜欢
      • 1970-01-01
      • 2018-07-22
      • 2011-03-07
      • 1970-01-01
      • 2016-11-09
      • 2014-05-31
      • 1970-01-01
      • 2016-05-20
      • 1970-01-01
      相关资源
      最近更新 更多