【问题标题】:Extract substring from a field with single awk in AIX在 AIX 中从具有单个 awk 的字段中提取子字符串
【发布时间】:2021-12-29 10:56:14
【问题描述】:

我有一个文件file,内容如下:

stringa    8.0.1.2     stringx
stringb    12.01.0.0    stringx

我必须从字段 2 中获取一个子字符串(前两个带有点的值)。
我目前正在做cat file | awk '{print $2}' | awk -F. '{print $1"."$2}' 并获得预期的输出:

8.0
12.01

查询是如何用单个 awk 做到这一点的?
我已经尝试使用 match() 但没有看到反向引用的选项。 任何帮助将不胜感激。

【问题讨论】:

    标签: awk grep ksh aix


    【解决方案1】:

    你可以这样做。

    $ awk '{ split($2,str,"."); print str[1]"."str[2] }' file
    8.0
    12.01
    

    另外,请记住您的cat 不是必需的。只需将文件直接提供给awk

    【讨论】:

      【解决方案2】:

      我会使用 GNU AWKsplit 函数如下,让 file.txt 内容为

      stringa    8.0.1.2     stringx
      stringb    12.01.0.0    stringx
      

      然后

      awk '{split($2,arr,".");print arr[1]"."arr[2]}' file.txt
      

      输出

      8.0
      12.01
      

      解释:在. 2nd 字段拆分并将元素放入数组arr

      (在 gawk 4.2.1 中测试)

      【讨论】:

        【解决方案3】:

        你可以匹配 digitsdigits 来自第二列,如果匹配则打印:

        awk 'match($2, /^[[:digit:]]+\.[[:digit:]]+/) {
            print substr($2, RSTART, RLENGTH)
        }
        ' file
        

        输出

        8.0
        12.01
        

        【讨论】:

          【解决方案4】:

          使用 GNU grep 请尝试以下命令一次。

          grep -oP '^\S+\s+\K[[:digit:]]+\.[[:digit:]]+' Input_file
          

          说明:在这里使用 GNU grep。使用其-oP 选项打印匹配的部分并在此处使用-P 选项启用PCRE。在主程序中,从非空格字符开始匹配,后跟 1 个或多个空格,然后使用 \K 选项忘记匹配。然后匹配 1 个或多个数字出现,后跟一个点;后面是数字。如果找到匹配项,则打印匹配的值。

          【讨论】:

          • grep -oP '^\S+\s+\K([[:digit:]]+\.){3}[[:digit:]]+' 文件 8.0.1.2 12.01.0.0
          • @vijesh,已编辑,请查看我的最新解决方案一次。
          • 打印整个字段2
          • @vijesh,请。它已被编辑,请查看我的最新/更新解决方案一次。
          • grep -oP '^\S+\s+\K[[:digit:]]+\.[[:digit:]]+' 文件有效!
          【解决方案5】:

          同样适用于 GNU awkgensub()

          awk '{print gensub(/([[:digit:]]+[.][[:digit:]]+)(.*)/,"\\1","g",$2)}' file
          8.0
          12.01
          
          • gensub() 提供了在替换文本中指定正则表达式组件的能力,使用正则表达式中的括号来标记组件,然后在替换文本中指定 \\n,其中 n 是从 1 到 9 的数字。李>

          【讨论】:

            【解决方案6】:

            您可能根本不应该使用 awk(或任何其他外部程序,就此而言),而应依赖 shell 的字段拆分功能和一些变量扩展。例如:

             # printf "%s\n%s\n" "stringa    8.0.1.2     stringx" \
                                 "stringb    12.01.0.0    stringx" |\
               while read first second third junk ; do
                    printf "=%s= =%s= =%s=\n" "$first" "$second" "$third"
               done
               =stringa= =8.0.1.2= =stringx=
               =stringb= =12.01.0.0= =stringx=
            

            正如您所见,该值已在变量“$second”中捕获,您只需要进一步隔离您想要查看的部分 - 第一部分和第二部分用点分隔。您可以通过参数扩展来做到这一点:

             # variable="8.0.1.2"
             # echo ${variable%.*.*}
               8.0
            

            或者像这样:

             # variable="12.01.0.0"
             # echo ${variable%${variable#*.*.}}
               12.01
            

            或者您可以使用进一步的读取语句将部分分开,然后将它们重新组合在一起:

             # variable="12.01.0.0"
             # echo ${variable} | IFS=. read parta partb junk
             # echo ${parta}.${partb}
               12.01
            

            所以,把所有东西放在一起:

             # printf "%s\n%s\n" "stringa    8.0.1.2     stringx" \
                                 "stringb    12.01.0.0    stringx" |\
               while read first second third junk ; do
                    printf "%s\n" "$second" | IFS=. read parta partb junk
                    printf "%s.%s\n" "$parta" "$partb"
               done
               8.0
               12.01
            

            【讨论】:

              猜你喜欢
              • 2015-05-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-07-05
              • 1970-01-01
              • 1970-01-01
              • 2014-11-10
              • 2019-12-21
              相关资源
              最近更新 更多