【问题标题】:How to make this awk command more simple如何使这个 awk 命令更简单
【发布时间】:2014-05-12 13:46:37
【问题描述】:

有没有办法让这个命令更简单(即不使用 awk 两次):

awk '/cpu MHz/ {print $4}' < /proc/cpuinfo | awk -F'.' 'NR==1 {print $1}'

?

另外,有没有办法避免在这里使用 cut 命令:

ip addr show dev eth0 | awk '$1=="inet" {print $2}' | cut -f1 -d '/'

?

谢谢。

【问题讨论】:

  • 在我看来这确实应该是两个问题。另外,我建议将示例输入和预期输出添加到问题中。例如,/proc/cpuinfo/ 的内容、ip addr show dev eth0 的输出以及您尝试提取的部分。
  • 包含输入样本和所需输出总是有帮助的。
  • awk '/cpu MHz/ { print int($4) }' /proc/cpuinfo? ip addr show dev eth0 | awk '/inet / { print gensub("/.*", "", "", $2) }'?
  • @twalberg 除了使用int() 函数,您只需添加0 即可。 awk '/cpu MHz/ { print $4+0 }' /proc/cpuinfo
  • @jaypal 我怀疑这取决于版本。我的awk 版本在我echo 1.5 | awk '{print $0+0}' 时给出“1.5”... 或者这是小数点后的数字全为零的结果。不过,在一般情况下显然不是这样......

标签: linux awk cut gawk


【解决方案1】:

第一个是这样的:

awk '/cpu MHz/ {print $4}' < /proc/cpuinfo | awk -F'.' 'NR==1 {print $1}'

考虑到你有一个这样的字符串:

cpu MHz         : 800.000
cpu MHz         : 800.000
cpu MHz         : 800.000
cpu MHz         : 800.000

而你想要数字的整数部分只用于第一行,你可以这样做:

$ awk -F"[ .]" '/cpu MHz/ {print $(NF-1); exit}' /proc/cpuinfo
800

即匹配行,打印倒数第二个字段,然后退出,避免额外处理。

根据 cmets,您还希望在不同的命令中获取第二个匹配行。为此,您可以这样做:

awk -F"[ .]" '/cpu MHz/ {if (f) {print $(NF-1); exit}; f=1}' /proc/cpuinfo

它的作用是使用标志。在第一次匹配时,标志被激活,因此在下一次匹配时它会打印值并退出。


第二个是这样的:

ip addr show dev eth0 | awk '$1=="inet" {print $2}' | cut -f1 -d '/'

您可以做的是根据/ 将第二个字段拆分为切片并打印第一个:

$ ip addr show dev eth0 | awk '$1=="inet" {split($2, a, "/"); print a[1]}'
192.168.123.123

【讨论】:

  • 谢谢。但是我如何为第二行制作另一个呢?我的 cpuinfo 中有这个: cpu MHz : 1000.000 cpu MHz : 1000.000
  • @user3628725 查看我的更新。另外,如果我的解决方案不符合您的要求,请使用您当前的示例输入进行更新,以便我猜出什么不起作用。
  • 谢谢,带有 ip addr show 的东西可以工作。关于第一个问题,我需要提取第一行和第二行(在两个单独的命令中)。如何调整您建议的命令以匹配第二行?
  • @user3628725 我刚刚更新了一个版本来打印第二行的匹配。
【解决方案2】:

如果目标是在您的界面上显示 IP 地址,那么这不是一个好的选择:

ip addr show dev eth0

如果接口有另一个名称,或者您有多个接口并且eth1 是连接到互联网的接口,该怎么办?

改用这个:

ip route get 8.8.8.8 | awk '/8.8.8.8/ {print $NF}'
192.168.0.33

将其存储在变量中:

IP=$(ip route get 8.8.8.8 | awk '/8.8.8.8/ {print $NF}')

它使用ip route 命令查看如何访问公共 IP,因此对于任何名称的接口都可以正常工作。

【讨论】:

  • 谢谢@Jotne,对我来说没关系(我只有一个界面),不过我会用,比较简单。
  • @daimonion 欢迎您。如果您将服务器移动到 VPS 场,则单个 if 可能会被命名为:venet0
  • +1;是否建议在awk 程序中重复输入IP 地址进行匹配,或者ip route get 8.8.8.8 | awk '{print $NF; exit}' 也可以?
  • @mklement0 事实上这也有效:ip route get 1 | awk '{print $NF;exit}'
  • 谢谢,有趣;这行得通,因为1 被解释为1.0.0.0,这显然是一个有效的地址。
猜你喜欢
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
  • 2021-12-12
  • 2013-01-20
  • 2014-08-15
相关资源
最近更新 更多