仅使用grep命令获取空格后面的第二部分

4
我可以帮忙翻译,以下是您需要翻译的内容:

我有一个Shell脚本中的解析器:

这是要从中解析的输入文件(input.txt):

input.txt:
system.switch_cpus.commit.swp_count                 0                       # Number of s/w prefetches committed
  system.switch_cpus.commit.refs                2682887                       # Number of memory references committed
  system.switch_cpus.commit.loads               1779328                       # Number of loads committed                                                                                                                                                                                                                
  system.switch_cpus.commit.membars                   0                       # Number of memory barriers committed
  system.switch_cpus.commit.branches             921830                       # Number of branches committed
  system.switch_cpus.commit.vec_insts                 0                       # Number of committed Vector instructions.
  system.switch_cpus.commit.fp_insts                  0                       # Number of committed floating point instructions.
  system.switch_cpus.commit.int_insts          10000000                       # Number of committed integer instructions.

这个脚本会执行以下操作:
 $ cpu1_name="system.switch_cpus"
 $ echo "$(grep "${cpu1_name}.commit.loads" ./input.txt |grep -Eo '[0-9]+')"
 correct expected output: 1779328

但是在另一个文件中,“cpu1_name”变量更改为“system.switch_cpus_1”。现在运行相同的脚本会给我2个值:

New input file:
system.switch_cpus_1.commit.swp_count               0                       # Number of s/w prefetches committed
 system.switch_cpus_1.commit.refs              2682887                       # Number of memory references committed
 system.switch_cpus_1.commit.loads             1779328                       # Number of loads committed                                                                                                                                                                                                               
 system.switch_cpus_1.commit.membars                 0                       # Number of memory barriers committed
 system.switch_cpus_1.commit.branches           921830                       # Number of branches committed
 system.switch_cpus_1.commit.vec_insts               0                       # Number of committed Vector instructions.
 system.switch_cpus_1.commit.fp_insts                0                       # Number of committed floating point instructions.   


Modified Script line:
$ cpu1_name="system.switch_cpus_1"
$ echo "$(grep "${cpu1_name}.commit.loads" ./new_input.txt |grep -Eo '[0-9]+')"
1
1779328

你可以看到,管道连接的grep命令会查找任何数字,并由于变量名称的更改而报告额外的“1”。

有没有办法只选择数字的第二部分(即仅1779328)? 我知道我可以使用awk'{print $2},但这意味着需要在脚本中更改很多行。所以我想知道是否有现有脚本行的更简单的技巧。

提前感谢

4个回答

1

Awk可以一步完成所有操作(无需管道):

awk -v x="${cpu1_name}.commit.loads" '$1==x{print $2}' input.txt

这应该是可移植的,并且可以与任何POSIX awk一起使用。

示例

$ awk -v x="${cpu1_name}.commit.loads" '$1==x{print $2}' input.txt
1779328
$ awk -v x="${cpu1_name}.commit.loads" '$1==x{print $2}' new_input.txt
1779328

工作原理

  • -v x="${cpu1_name}.commit.loads"

    这定义了一个 awk 变量 x,其中包含我们要查找的名称。

  • $1==x{print $2}

    如果第一个字段 $1 等于 x,则打印第二个字段 $2


1
显然,您要获取的值(数字)周围都有空格。因此,您可以使用正向后查找 (?<=pattern) 和正向前查找 (?=pattern) 正则表达式条件来查找那些在其周围有空格的匹配项。
请注意,要使用这些条件,您需要在 grep 中使用 -P 标志。

@MadPhysicist 他们使用 -P 标志。 - Martin Heralecký
@MadPhysicist:是的,如果你使用带有“-P”标志的Perl正则表达式模式,它们会生效。只需检查我的答案即可。 - Allan
不错。今天学到了新东西。+1 - Mad Physicist

1

由于_被认为是单词字符,因此在_1之间没有单词边界。期望数字两侧都有单词边界。

因此,您只需要使用带有单词边界的模式即可。您可以使用w选项进行整个单词匹配,或者选择\b\</\>,取决于您的grep支持哪种方式:

grep -Ewo '[0-9]+'
grep -Eo '\b[0-9]+\b'
grep -Eo '\<[0-9]+\>'

请查看在线演示

请注意,您也可以使用sed从行中提取第二个非空白块:

sed -E 's/^\s*\S+\s+(\S+).*/\1/'

请查看此演示。

详细信息

  • ^ - 行首
  • \s* - 0个或多个空格字符
  • \S+ - 1个或多个非空白字符
  • \s+ - 1个或多个空白字符
  • (\S+) - 1个或多个非空白字符(第一组,使用\1占位符在替换模式中保留)
  • .* - 行的剩余部分。

0

你只需要修改你的grep命令为:

grep -oP '(?<=\s)[0-9]+'

为了在数字链前面添加空格,更好的方法是尝试以下代码:

grep -oP '(?<=\s)\d+'

或者最终在grep -oP '(?<=\s)\d+(?=\s)'grep -oP '(?<=\s)[0-9]+(?=\s)'中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接