【问题标题】:AWK sub function syntaxAWK 子函数语法
【发布时间】:2014-11-24 15:25:43
【问题描述】:

我有一个包含内容的文件:

aaa.bbb.ccc ddd.eee.fff.ggg h.i.j.k

如果我使用代码:

awk '{sub(/\.$/, ""); print $1}' test.txt
returns    aaa.bbb.ccc

awk '{sub(/\.$/, ""); print $3}' test.txt
Returns: h.i.j.k

我理解 sub 函数被用作:sub(regexp, replacement, target)

我不明白这部分.$/,来自子函数。 .$ 是什么?

谢谢

更新

好的,我喜欢你解释事情的方式——谢谢!

如果我把这个应用到一个真实的例子中,

/usr/bin/host 172.0.0.10

01.0.0.172.in-addr.arpa 域名指针hostname.domain.com.

  1. /usr/bin/host 172.0.0.10 | /bin/awk '{sub(/.$/, "");打印 $5}' 给出:hostname.domain.com

  2. /usr/bin/host 172.0.0.10| /bin/awk '{sub(/.$/, "");打印 $1}' 给出:10.0.0.172.in-addr.arpa

-子函数将匹配到行尾,因为有一个“。” -“”在做什么? -我不明白 awk 是如何将内容拆分为列的?

【问题讨论】:

    标签: regex awk


    【解决方案1】:
    sub(/regexp/, replacement, target)
    sub(/\.$/, replacement, target)
    

    你的正则表达式是\.$,而不是.$/

    \ 是转义字符。它会转义后面的字符,从而将其从 regex 的含义中剥离出来并按字面意思进行处理。

    . in regex 匹配任何单个字符。除非它像您的示例中那样被\ 转义,否则它只匹配点字符.

    $ 仅表示行尾。

    综上所述,\.$ 是行尾的转义点。例如,这将匹配以句点结尾的任何段落结尾。

    在您的示例中,sub 不会替换任何内容,因为行尾没有 .(您的输入以 .k 结尾。所以您的第一个 awk 只打印第一列,另一个打印第三列。

    更新

    对于您更新的问题。

    默认情况下,Awk 通过空格将字符串拆分为列。因此,在您的输入中,列是这样的:

     01.0.0.172.in-addr.arpa domain name pointer hostname.domain.com.
    |----------$1-----------|--$2--|-$3-|--$4---|----------$5--------|
    

    在您的sub 命令中,awk 找到行尾的点并替换为空字符串""(即它只是将其删除)

    所以你的第一个命令 - {sub(/.$/, ""); print $5},它打印第 5 列,即 hostname.domain.com.,在它用任何内容替换末尾的 .(删除它)之后。值得注意的是,在此正则表达式中,您不再转义 .,因此该模式仅匹配末尾的 any 字符并将其删除(它恰好是您输入中的 . )

    您的其他命令 - {sub(/.$/, ""); print $1} 删除行尾的字符,然后只打印第一列 10.0.0.172.in-addr.arpa

    您还可以在 awk 中设置自定义列分隔符,我建议您阅读一些有关 awk 的介绍和教程,以更好地了解它的工作原理。例如。 simple awk tutorial

    【讨论】:

    • 谢谢,你很擅长解释事情。我已经扩展了。查看更新
    • 再次感谢您抽出宝贵时间指导我,我现在明白了!我不知道默认情况下按空格分割,并认为它用“。”做了一些聪明的事情。一个非常有建设性的答案,我将进一步阅读 awk 和正则表达式。为你的时间喝彩,赞!
    【解决方案2】:

    sub(regexp, replacement, target)

    所以这里我们使用正则表达式为\.$,它与末尾的点匹配。这里sub(/\.$/, "") 我们没有提到目标所以它需要$0 即整行。如果您指定任何 target ,它将仅删除该特定列上的最后一个点。

    awk '{sub(/\.$/, ""); print $1}' test.txt
    

    删除仅出现在行尾的点并仅打印第 1 列。如果最后没有点,则不会发生替换。

    awk '{sub(/\.$/, ""); print $3}' test.txt
    

    删除行尾的点并仅打印第 3 列。由于末尾没有点,它返回第三列,即最后一列。

    示例:

    $ cat file
    aaa.bbb.ccc. ddd.eee.fff.ggg h.i.j.k.
    $ awk '{sub(/\.$/, ""); print $1}' file
    aaa.bbb.ccc.
    $ awk '{sub(/\.$/, ""); print $3}' file
    h.i.j.k
    

    【讨论】:

      【解决方案3】:

      我有一张这种格式的桌子

      <table width="700" border="1" align="center" cellpadding="0" cellspacing="0" bordercolor="ffcc00" bgcolor="ffcc00">
      <tbody>
              <th colspan="7" bordercolor="ffcc00" bgcolor="000000" scope="col">
                  <div align="center" class="style2">
                      Exciter Power Supply</div>
              </th>
          </tr>
          <tr>
              <th width="175" bordercolor="ffcc00" bgcolor="000000" scope="col">
                  <div align="center" class="style1">+ 3 V </div>
              </th>
              <th width="175" bordercolor="ffcc00" bgcolor="000000" scope="col">
                  <div align="center" class="style1">
                      OK</div>
              </th>
              <th width="175" bordercolor="ffcc00" bgcolor="000000" scope="col">
                  <div align="center" class="style1">&nbsp;+ 5 V</div>
              </th>
              <th width="175" bordercolor="ffcc00" bgcolor="000000" scope="col">
                  <div align="center" class="style1">
                      OK</div>
              </th>
          </tr>
          
      </tbody>
      

      当我得到+3 V

      的值时
      curl -s http://my-site/index.htm | sed -e 's/<[^>]*>//g' | awk '/+ 3 V/{getline;  print}'
      

      我的输出OK'&nbsp'; + 5 伏

      为了删除另一个字段的空格和文本,我使用 sub() 来更改字符加上 tr 来删除字符

      curl -s http://my-site/index.htm | sed -e 's/<[^>]*>//g' | awk '/+ 3 V/{getline; sub(/+ 5 V/, ""); print}' | tr "&nbsp;" " "
      

      我的输出只有OK

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-07
        • 2019-10-06
        • 1970-01-01
        • 2018-08-20
        • 2021-02-03
        • 2018-07-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多