如何从一行中提取数字并将其保存到变量中?

Dan*_*lan 2 grep sed regular-expression

我觉得这是一个非常简单的问题,当我谷歌时,我为部分问题找到了很多答案,但是当我尝试将它们放在一起时,它不起作用,我无法弄清楚为什么。

这是场景:

  1. 我有一个包含大量文本的文件。
  2. 其中一行与此模式匹配: foo = 1700;
  3. 我想提取 1700
  4. 我想将它保存到 bash 脚本变量中,以便稍后在脚本中引用它。

我无法通过第 3 步。这是我尝试过的:

sed -nE 's/^foo = //p' file | sed -nE 's/;//p'
Run Code Online (Sandbox Code Playgroud)

这打印出来:

1700
Run Code Online (Sandbox Code Playgroud)

很好,但是如果我需要修剪空白或其他东西怎么办?如果我不能使用*/ +,我就不知道该怎么做。我了解到您不能在另一个答案中使用*/+替代,所以我不知道如何做到这一点。我查看了 grep 的手册页,当我搜索该词时,我没有看到任何组选项。我想我知道如何在 awk 中解决这个问题,但我一直发现它的正则表达式函数有点笨拙,而且命令行脚本需要太多的转义,所以理想情况下这不是解决这个问题的唯一方法。

cas*_*cas 7

  1. 首先,以下是捕获数值的方法:

    $ echo 'foo = 1700;' | sed -n -e 's/^foo = \([0-9]\+\).*/\1/p'
    1700
    
    Run Code Online (Sandbox Code Playgroud)

    那是使用sed的默认基本正则表达式 (BRE)。您还可以使用带有 sed-E选项的扩展正则表达式 (ERE) :

    echo 'foo = 1700;' | sed -n -E -e 's/^foo = ([0-9]+).*/\1/p'
    1700
    
    Run Code Online (Sandbox Code Playgroud)

    [0-9]+括号内的子表达式(...)捕获一个或多个数字。这称为“捕获组”,用于替换为\1(这是第一个捕获组 - 如果有多个捕获组,它们可以用作 \1、\2、\3 等)。

    在这种情况下,sed 脚本尝试仅用 \1 捕获组替换整行,如果成功,则打印修改后的行。

  2. 接下来,您希望将sed的输出放入一个变量中。您可以使用命令替换来做到这一点。例如

    $ myvar=$(echo 'foo = 1700;' | sed -n -E -e 's/^foo = ([0-9]+).*/\1/p')
    $ echo $myvar
    1700
    
    Run Code Online (Sandbox Code Playgroud)
  3. 要在您的脚本中使用它,只需将您的文件用作 sed 的参数,而不是通过管道echo ...输入它。

    myvar=$(sed -n -E -e 's/^foo = ([0-9]+).*/\1/p' file)
    
    Run Code Online (Sandbox Code Playgroud)
  4. 修剪空格,或处理可能有可选前导空格或 周围可选空格=等的行:

    myvar=$(sed -n -E -e 's/^[[:space:]]*foo[[:space:]]*=[[:space:]]*([0-9]+).*/\1/p' file)
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,某些版本的 sed(至少是 GNU sed。也许其他版本)可以理解perl's \s,因此您可以将其缩短为:

     myvar=$(sed -n -E -e 's/^\s*foo\s*=\s*([0-9]+).*/\1/p' file)
    
    Run Code Online (Sandbox Code Playgroud)

  • 好的,这解释了我一直遇到的唯一问题。谢谢! (2认同)
  • @DanielKaplan 在您的问题中没有提到任何地方 (2认同)