【问题标题】:grep awk ignore charactergrep awk 忽略字符
【发布时间】:2013-11-28 19:26:54
【问题描述】:

我正在尝试 grep “选项 dhcp-server-identifier”的值,即 192.168.75.1;

我不确定如何忽略 IP 地址末尾的分号“;”。

[root@localhost ~]# cat /var/lib/dhclient/dhclient-eth0.leases
lease {
interface "eth0";
fixed-address 192.168.75.54;
option subnet-mask 255.255.255.0;
option routers 192.168.75.1;
option dhcp-lease-time 4294967295;
option dhcp-message-type 5;
option domain-name-servers 192.168.75.1,8.8.8.8;
option dhcp-server-identifier 192.168.75.1;
option broadcast-address 192.168.75.255;
option host-name "centos-64-x86-64";
option domain-name "cs2cloud.internal";
renew 1 2081/12/15 18:43:55;
rebind 2 2132/12/30 03:09:24;
expire 6 2150/01/03 21:58:02;
}

我已经尝试了以下

grep  dhcp-server-identifier /var/lib/dhclient/dhclient-eth0.leases | awk '{print $3}' 

结果是 192.168.75.1;

谢谢

【问题讨论】:

    标签: linux bash awk grep


    【解决方案1】:

    使用awk

    awk -F" |;" '/dhcp-server-identifier/ {print $3}' /var/lib/dhclient/dhclient-eth0.leases
    192.168.75.1
    

    【讨论】:

    • +1 但 `|;` 应该是 [ ;] 以确保清晰、稳健等。不过是一个小细节。
    • @EdMorton 你能解释一下为什么[ ;]" |;" 更健壮吗?我以为是一样的。 First 表示方括号中的任何字符。第二个表示空格或;
    • a|b 表示“RE a 或 RE b”,而 '[ab]' 表示 character a or character b。想象一下,发帖人将来决定他们只想要 IP 地址的第一部分,而不是 @ 987654329@ 他们只想要192。他们可能会将您的脚本更改为awk -F" |." '/dhcp-server-identifier/ {print $3}',然后由于. 是RE 元字符而导致脚本失败时感到惊讶。而如果您从-F'[ ;]' 开始,他们可以简单地更改到-F'[ .]',它会按预期工作。
    • @EdMorton 感谢您的解释。我知道你必须逃避.。我明白你的观点和陷阱。 :)
    【解决方案2】:

    请记住,如果您想使用 awk,则可以简单地使用 awk。以下是等价的:

    $ grep  dhcp-server-identifier /var/lib/dhclient/dhclient-eth0.leases | awk '{print $3}'
    $ awk  '/dhcp-server-identifier/ {print $3}' /var/lib/dhclients/dchclicent-eth0.leases
    

    您的问题是分号出现在名称的末尾。我们可以使用 awk 的 substr 函数来删除最后一个字符,而不是简单地打印 $3。这是对 awk 手册页的引用:

    substr(s, m, n)
    s 的 n 个字符的子串,从位置 m 开始,从 1 开始计数。

    length 作为字符串的参数的长度,如果没有参数,则为 $0。

    所以,我们需要$3的子字符串从第一个位置(1)到$3减去最后一个字符的长度,所以我们需要从第一个字符到length ($3) - 1

    substr($3, 1, length($3) - 1)
    

    应该这样做:

    $ awk  '/dhcp-server-identifier/ {print substr($3, 1, length($3) - 1)}' /var/lib/dhclients/dchclicent-eth0.leases
    

    应该可以的。

    【讨论】:

      【解决方案3】:

      awk 函数substr 呢:

      ~ $ echo "Hello My Friend!" | awk '{print substr($3,0,length($3)-1)}'
      Friend
      

      关于 AWK 的注意事项

      Awk 是一种非常强大且完整的编程语言。如果您发现自己每天使用它不止一次,那么通过学习更多内容(尤其是正则表达式处理部分),您可以真正受益于您每天的 bash 工作流程。

      来源:The AWK Manual

      【讨论】:

        【解决方案4】:

        sed:

        sed -n 's/.*option dhcp-server-identifier \(.*\);/\1/p' file
        

        使用grepegrep

        grep 'option dhcp-server-identifier' file  | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'
        

        输出:

        192.168.75.1
        

        【讨论】:

          【解决方案5】:
          grep  dhcp-server-identifier /var/lib/dhclient/dhclient-eth0.leases | cut -d ' ' -f3 | cut -d';' -f1
          

          命令说明:获取具有“dhcp-server-identifier”的行。按空间分割,并显示第三个选择。用';'分割并显示第一个选择。

          hek2mgl 答案是我更喜欢使用的答案;但对于初学者,我通常建议使用比 sed 更简单的工具。

          【讨论】:

          • 我记得cut 也是我选择的工具的时候 :).. +1 让它工作(这很重要:) @987654323 @ 或一般说的 POSIX 正则表达式并不难。尝试获取 Oreilly Sed and Awk
          【解决方案6】:

          awk 版本:

          awk -F'[ ;]' '/dhcp-server-identifier/ {print $(NF-1)}' /var/lib/dhclient/dhclient-eth0.leases
          

          使用 NF-1 更安全,以防你有更多的空格。

          perl 版本:

          perl -ne 'print if s/^.*dhcp-server-identifier +([0-9.]+);$/$1/' /var/lib/dhclient/dhclient-eth0.leases
          

          我认为这是最安全的 1-liner。

          hek2mglsed 版本也不错。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-02
            • 1970-01-01
            • 1970-01-01
            • 2017-10-23
            • 1970-01-01
            • 2011-08-07
            相关资源
            最近更新 更多