如何从一行中提取特定数据

如何从一行中提取特定数据

问题

我正在寻找 Bash 中的一种解决方案,可以在指定字符串后提取特定信息。

例子

例如(从运行acpi):

Battery 0: Discharging, 37%, 01:33:20 remaining

我怎样才能提取出院后的百分比?在这种情况下,它将是37%...

笔记

我正在寻找一个不需要大量命令参数的简单解决方案。

答案1

以下是其中几点:

$ acpi | grep -oP '\d+%'
99%
$ acpi | awk -F',' '{print $2}'
 99%
$ acpi | perl -pe 's/.*?(\d+%).*/$1/'
99%

答案2

我不确定您说的“bash 中的解决方案”是什么意思,但awk可以完成这项工作:

awk -F", " '{print$2}'
  • -F", "– 选择逗号加空格作为字段F分隔符,这会将示例行分成三列,其中第二列是37%
  • '{print$2}'– 打印第二列

或者怎么样sed

sed -E 's/.* ([0-9]+%).*/\1/'

答案3

我正在寻找 bash 中的解决方案,可以在指定字符串后提取特定信息。

指定的字符串?之前发布的两个答案都没有具体做到这一点(因为在字符串之后抓取文本并不是获取您在示例中所说的所需信息的最佳方式)。

以下是获取字符串后文本的几种方法。我使用了您的示例,尽管甜点的答案terdon 的回答两者都针对这一特殊情况提出了更为合适的方法。

从 Perl 中使用\K,例如在grep-P允许 Perl 正则表达式)和-o(仅匹配)中:

grep -Po 'string\Kdesired'

哪里string是匹配您想要的内容之前的表达式,哪里desired是匹配您想要输出的内容的表达式。当您想要的模式出现在文件/行中的其他地方时(例如,它是一个数字,而文件/行包含其他数字),这很有用。在您的示例中,这可能是这样的:

$ acpi | grep -Po 'ing, \K[^,]+'
79%

[^,]+表示一些不是逗号的字符,因此这可以抓取逗号之前的文本。我们也可以使用...来获取任意三个字符,但正如PerlDuck 的评论,您在此处想要的模式可能多于或少于 3 个字符。

在 中sed,您可以将捕获组与(和 一起使用)

sed -r 's/.*string(desired).*/\1/' 

\1保存的内容在哪里( )。例如:

$ acpi | sed -r 's/.*ing, ([^,]+).*/\1/'
89%

以下是仅使用 Bash 执行此操作的方法

$ output=$(acpi); string="${output#*ing, *}"; desired="${string%,*}"; echo "$desired"
96%

${var#string*}修剪var之前string(包含)和${var%string*}修剪var之后string(包含)。

这绝不是一个详尽的清单。有很多方法可以做到这一点 :)

答案4

您还可以使用子字符串提取参数扩展

input=$(acpi)
expr "${input#*,[[:space:]]}" : '\([^,]*\)'

相关内容