如何从一行中提取某些数据

Ner*_*ode 8 command-line text-processing

问题

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

例子

例如(从运行acpi):

Battery 0: Discharging, 37%, 01:33:20 remaining
Run Code Online (Sandbox Code Playgroud)

出院后如何提取百分比?在这种情况下,它将是37%......

笔记

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

ter*_*don 13

以下是一些:

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


des*_*ert 10

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

awk -F", " '{print$2}'
Run Code Online (Sandbox Code Playgroud)
  • -F", "– 选择逗号后跟空格作为F字段分隔符,这会将您的示例行分成三列,其中第二列是37%
  • '{print$2}' – 打印第二列

或者怎么样sed

sed -E 's/.* ([0-9]+%).*/\1/'
Run Code Online (Sandbox Code Playgroud)


Zan*_*nna 9

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

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

以下是在字符串后获取文本的几种方法。我已经使用了你的例子,尽管甜点的答案terdon 的答案都展示了更适合这种特殊情况的方法。

\K从 Perl使用,例如在grepwith -P(allow Perl regex) and -o(match only) 中:

grep -Po 'string\Kdesired'
Run Code Online (Sandbox Code Playgroud)

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

$ acpi | grep -Po 'ing, \K[^,]+'
79%
Run Code Online (Sandbox Code Playgroud)

[^,]+意味着一些不是逗号的字符,所以这可以抓取文本直到逗号。我们也可以使用...获取任何三个字符,但正如PerlDuck评论中指出的那样,您在这里想要的模式可能会多于或少于 3 个字符。

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

sed -r 's/.*string(desired).*/\1/' 
Run Code Online (Sandbox Code Playgroud)

\1( ).保存的内容在哪里?对于您的示例:

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

这是一种仅在您的示例中使用 Bash 的方法

$ output=$(acpi); string="${output#*ing, *}"; desired="${string%,*}"; echo "$desired"
96%
Run Code Online (Sandbox Code Playgroud)

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

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


小智 6

一个 bash 解决方案,根据要求,没有尴尬的 awkisms 或刻意的煽动:

my_battery=( $(acpi) ); echo ${my_battery[3]}
Run Code Online (Sandbox Code Playgroud)

这使用命令替换,制作命令输出的数组,并显示数组的第 4 个元素。

这适用于 acpi 的输出,它似乎总是将电池百分比作为第四个参数。如果您想在“放电”之后找到数组的元素,如果 acpi 告诉您“电池 0:已满,100%”,您将不会得到结果。