linux 我应该使用哪个工具从字符串中提取数据?[已关闭]

rdlzhqv9  于 2023-10-16  发布在  Linux
关注(0)|答案(6)|浏览(101)

**已关闭。**此问题正在寻求书籍、工具、软件库等的建议。它不符合Stack Overflow guidelines。它目前不接受回答。

我们不允许问题寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答问题。
18天前关闭
Improve this question
作为一个相当新的Linux用户,我从来没有(真正)使用过像sedawk(或任何其他)这样的工具来解析文本。我想从
速度:1624.127424 Kib/s,9.410000秒
以秒为单位的时间值,正好在seconds字之前,
我应该使用哪种工具来实现这一点?

js81xvg6

js81xvg61#

有很多工具可以使用,但awk可以很好地使用:

echo "Speed : 1624.127424 Kib/s in 9.410000 seconds" | awk '{print $6}'

或者(如果您的数据在文件中):

awk '{print $6}' data.txt

给你

9.410000
  • 说明 *:

这假设你感兴趣的值在行上的相对位置保持不变(在本例中是第6个空格分隔的字段),相应地进行调整。
awk将输入行拆分为基于空白的字段。您感兴趣的字段是第6个字段,因此您将使用$6打印该字段。
或者,您也可以使用awk '{print $(NF-1)}'打印该行上的倒数第二个字段(NF是一个awk变量,它知道给定行上的字段数)。这提供了更多的灵活性,因为它将与长度线(即字段数),只要你感兴趣的领域是倒数第二)。

cut是另一个可以工作的工具:

echo "Speed : 1624.127424 Kib/s in 9.410000 seconds" | cut -d' ' -f 6

在这种情况下,行是基于空间的长度(如-d所指定的)来分割的,并且再次,我们对第6个字段(-f 6)感兴趣。
也有其他的方法,但这两个似乎直接向前,首先想到的。

xzlaal3s

xzlaal3s2#

或者,如果你不知道它在字符串中的确切位置,但你知道它在单词'seconds'之前,你可以使用sed。这涉及到正则表达式,它不像计算字段那样简单,但它们允许您从可能没有这种严格约束格式的字符串中获取数据。这里有一种方法(<<<只是另一种将字符串作为命令输入的方法):

sed -n 's/^.* \([0-9.]\+\) seconds.*$/\1/p'  <<<"Speed : 1624.127424 Kib/s in 9.410000 seconds"

由于只有一行输入,-n/p在这里是无关的,但它们形成了一个有用的模式:它们告诉sed默认情况下不要打印所有的行,而只打印搜索和替换成功的那些行。
s/old/new/语法执行搜索和替换,其中“旧”部分是正则表达式模式。
模式[0-9.]\+ seconds匹配一个或多个数字或句号,后跟一个空格和单词“seconds”。在模式的一部分周围加上反斜杠括号,会导致与模式的这一部分匹配的实际字符串保存在变量中供以后使用;所以\([0-9.]\+\) seconds捕获所需的数字。
由于我们只想打印**那个值,所以我们把它放在^.*.*$之间,^.*匹配"从行首开始的所有内容“,.*$匹配”到行尾的所有内容“。这样,整条线路都将被替换。然而,由于.*是贪婪的,如果我们把它放在模式的前面,它会吃掉我们数字的最后一位,这是我们不想要的。在模式中的数字前添加空格可以防止这种情况。
我们用什么来代替这条线?使用\1,这是匹配(第一对)反斜杠括号之间的模式部分的字符串。

编辑添加:

问题中没有列出Perl,但与上述sed方法类似的方法是:

perl -lne 'print $1 if /([0-9.]+) seconds/'  <<<"Speed : 1624.127424 Kib/s in 9.410000 seconds"
lx0bsm1f

lx0bsm1f3#

如果变量中只有一个字符串,则可以使用shell本身。如果你知道它是第六个字段(就像@Levon的awk解决方案假设的那样),你可以这样做:

set -- $variable
seconds=$6

或者,如果你知道单词后面是单词seconds,你可以使用字符串替换;

prefix=${variable%\ seconds*}
seconds=${prefix##*\ }

(The临时变量包含了原始的带有空格后的任何内容,“秒”被修剪掉。同样,我们从最开始的最后一个空格开始修剪所有内容。)
不要低估了 shell ,它是相当多才多艺,虽然有时古怪。

wwodge7n

wwodge7n4#

仅仅为了完成,perl可以在类似awk的模式下运行。假设你的数据是在,那么data.txt

$ perl -lane 'print $F[5] data.txt'
9.410000

-a打开自动分割模式- perl会自动将空白处的输入行分割到@F数组中。

kqqjbcuj

kqqjbcuj5#

cut

echo "Speed : 1624.127424 Kib/s in 9.410000 seconds" | cut -f 6 -d' '

文档(摘录):
cut-从每一行文件中删除部分

-d, --delimiter=DELIM

使用DELIM而不是TAB作为字段扩展名

-f, --fields=LIST

仅选择这些字段;除非指定了-s选项,否则还将打印不包含任何字符的行

4sup72z8

4sup72z86#

通过RS使用awk的3种非常奇怪的方法::

echo 'Speed : 1624.127424 Kib/s in 9.410000 seconds' |
nawk 'END { print }'  RS='[^0-9.]+'
gawk  NF=NF==2 RS='.* in '
mawk  NF       RS='.* in |[^0-9.]+'
9.410000

相关问题