【问题标题】:How to get a string before a specific character in bash如何在bash中的特定字符之前获取字符串
【发布时间】:2020-10-29 06:51:22
【问题描述】:

我在lists.txt 文件中有一些内容如下:

abc.com.                IN A        10.120.51.95    ;10.40.40.57 ;old 10.20.3.57    
;def-mytaxi.com.        IN A        10.12.4.9   ;10.40.3.43 ;test
xyz-mytaxi.com.     IN CNAME        10.12.4.8   ;10.40.3.53 ;test

所以,我需要将这些写入另一个文件,所以

  1. 它应该避免任何以; - 2nd row is avoided 开头的行

  2. 它应该只选择带有IN A - only the 1st row is seletced 的行

  3. 它应该删除每个第一列末尾的训练. - remove . after abc.com.

  4. 它应该避免 ; 之后所选行中的任何值- therefore only prints abc.com 10.120.51.95

最终输出应该被写入一个文件,它应该看起来像;

abc.com 10.120.51.95

所以我写了这个脚本,但是除了3rd4th 步骤之外,一切都很好。

我得到的输出为:

abc.com.   10.120.51.95   10.40.40.57 old 10.20.3.57  

这是我尝试过的,有人可以帮助我吗?

awk '/IN A/ {$2=$3=""; print $0}' lists.txt  | sed '/^;/d;s/;//g;s/#//g' > updated_list.txt

【问题讨论】:

标签: linux bash awk


【解决方案1】:

您的条件非常明确且定义明确。所以整个工作可以通过awk 脚本来完成:

awk '/^;/ || (!/IN A/) {next}          # condition 1 and condition 2
     {sub(/IN A/,"",$0);$1=$1;$0=$0}   # condition 5, FS>OFS, recompute fields
     {sub(/[.]$/,"",$1)}               # condition 3
     {sub(/;.*$/,"",$0)}               # condition 4
     {sub(/[.]$/,"",$NF)}              # condition 6 (IP is now in last col)
     { print }' file
  • 条件 1 到 4 由 OP 给出。
  • 条件 5 想要删除 IN A
  • 条件 6 从 IP 中删除潜在的最终 .

【讨论】:

  • 工作正常,但我也需要摆脱 IN A 部分。这个输出提供了一切,但它有IN A
  • @JananathJayarathna 您的文件是制表符分隔、空格分隔还是未知?
  • 未知,而且一些 IP 在末尾有一个额外的.,我怎样才能像我们在第一列中那样摆脱它们?
【解决方案2】:

这个awk 也应该可以工作:

awk '!/^[[:blank:]]*;/ && / IN A / {
   sub(/\.$/, "", $1)
   print $1, $4
}' file
abc.com 10.120.51.95

【讨论】:

  • 这不仅会删除以; 开头的行,还会删除中间有; 的行
  • @JananathJayarathna 为了测试,请发布这样的失败行。不要将它们作为 cmets 或图像发布,请将它们编辑为原始帖子。谢谢。
  • @JananathJayarathna:我的答案中的输出与您的预期相同,对吧?
  • 你也可以试试我更新的答案。顺便说一句,发布所有带有预期输出的输入,并仅在检查它生成您的预期输出后接受答案。
【解决方案3】:

您能否尝试仅在 GNU awk 中使用所示示例进行跟踪、编写和测试。

awk '
!/^;/ && /IN A/{
  sub(/\.+$/,"",$1)
  match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ +;/)
  val=substr($0,RSTART,RLENGTH)
  sub(/ +;.*/,"",val)
  print $1,val
  val=""
}' Input_file

说明:为上述添加详细说明。

awk '                                  ##Starting awk program from here.
!/^;/ && /IN A/{                       ##Checking condition if line DO NOT start from ; AND has IN A in it then do following.
  sub(/\.+$/,"",$1)                    ##Substituting all dots trailing in first field with NULL here.
  match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ +;/)   ##Using match by mentioning regex to match IP address followed by space and followed by semi colon in here.
  val=substr($0,RSTART,RLENGTH)        ##Creating val variable which has sub string of matched regex in above statement.
  sub(/ +;.*/,"",val)                  ##Substituting all spaces and everything from semi colon to last of line in val here.
  print $1,val                         ##Printing first field and val here.
  val=""                               ##Nullifying val here.
}' Input_file                          ##Mentioning Input_file name here.

【讨论】:

  • @JananathJayarathna,它对我来说工作正常并且测试良好,如果你复制正确,请告诉我?
  • 语法消失了,但这不会打印 IP 地址/s
  • @JananathJayarathna,对不起,我没听懂,你是说语法错误?我已经用显示的示例对其进行了测试,它对我来说效果很好,您遇到了什么错误,请在此处发布。
  • @RavinderSingh13 嗯,已确认。它无法在 mawk 上打印 ip,有趣。和 awk 版本 20121220 所以它在 MacOS 中也可能失败。
  • @JamesBrown,感谢您的确认,这就是为什么我提到我在 GNU awk 上测试过它的原因 :) 你能告诉我这现在是否有效吗,我没有 mawk :)
【解决方案4】:
$ awk 'match($1,/^[^;].*/)&&$2=="IN"&&$3=="A"{print substr($1,RSTART,RLENGTH-1),$4}' file

输出:

abc.com 10.120.51.95

“解释”:

$ awk '
match($1,/^[^;].*/) && $2=="IN" && $3=="A" {     # match 
    print substr($1,RSTART,RLENGTH-1),$4         # and output
}' file

编辑:删除尾随的 .来自ip:

awk '
match($1,/^[^;].*/) && $2=="IN" && $3=="A" {
    print substr($1,RSTART,RLENGTH-1),
        ($4~/\.$/?substr($4,1,length($4)-1):$4)  # remove extra . from ip
}' 

【讨论】:

    【解决方案5】:

    试试这个:

    awk '/^[a-z].*IN A/{sub(/\.$/, "", $1); print $1, $4}' file
    

    【讨论】:

      【解决方案6】:

      另一种选择:

      awk '{ gsub(/;.*/,"")} / IN A / { gsub(/\.$/,"",$1); printf("%s %s\n",$1,$4)}' FILE
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-21
        • 1970-01-01
        • 2019-06-16
        • 2022-11-10
        • 2014-05-22
        • 2012-09-16
        相关资源
        最近更新 更多