Linux 我应该使用哪个工具从字符串中提取数据?

Linux 我应该使用哪个工具从字符串中提取数据?,linux,bash,sed,awk,Linux,Bash,Sed,Awk,作为一个全新的Linux用户,我从未(真的)使用诸如sed和awk(或任何其他)之类的工具来解析文本。 我想从中提取 速度:9.410000秒内1624.127424 Kib/s 以秒为单位的时间值,就在秒字之前 对此,我应该使用哪种工具?您可以使用多种工具,但都可以: echo "Speed : 1624.127424 Kib/s in 9.410000 seconds" | awk '{print $6}' 或者(如果您的数据在文件中): 给你 9.410000 说明: 这假设您感兴趣的

作为一个全新的Linux用户,我从未(真的)使用诸如
sed
awk
(或任何其他)之类的工具来解析文本。 我想从中提取

速度:9.410000秒内1624.127424 Kib/s

以秒为单位的时间值,就在
字之前


对此,我应该使用哪种工具?

您可以使用多种工具,但都可以:

echo "Speed : 1624.127424 Kib/s in 9.410000 seconds" | awk '{print $6}'
或者(如果您的数据在文件中):

给你

9.410000
说明:

这假设您感兴趣的值在该行上的相对位置将保持不变(在本例中为第6个空格分隔字段),请相应调整

awk
根据空格将输入行拆分为字段。您感兴趣的字段是第6个字段,因此您将使用
$6
打印该字段

或者,您也可以使用
awk'{print$(NF-1)}'
打印行上下一个字段(
NF
是一个awk变量,它知道给定行上的字段数)。这提供了更多的灵活性,因为只要您感兴趣的字段是倒数第二个字段,它就可以处理一条长度线(即字段数)

--

这将是另一个同样有效的工具:

echo "Speed : 1624.127424 Kib/s in 9.410000 seconds" | cut -d' ' -f 6
在这种情况下,根据空格分隔符(由
-d
指定)拆分行,我们同样对第6个字段(
-f 6
)感兴趣


还有其他的方法,但这两种方法似乎都是直截了当的,首先出现在我的脑海中。

还有,
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
选项


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

set -- $variable
seconds=$6
或者,如果您知道单词后面跟有单词
seconds
,则可以使用字符串替换

prefix=${variable%\ seconds*}
seconds=${prefix##*\ }
(临时变量包含原始变量,在空格后加上任何空格,“秒”将被修剪掉。我们同样会从该变量开头的最后一个空格中修剪所有内容。)


不要低估shell,它是非常通用的,尽管有时很古怪。

或者,如果您不知道它在字符串中的确切位置,但知道它在单词“seconds”之前,您可以使用
sed
。这涉及到正则表达式,正则表达式不像计算字段那样简单,但它们可以让您从可能没有严格约束格式的字符串中获取数据。这里有一种方法(仅用于完成,perl可以在类似awk的模式下运行

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

-a
打开自动拆分模式–perl将自动将空白处的输入行拆分为@F数组。

整洁的shell技巧,尤其是第二种。由于我主要使用
tcsh
我个人更喜欢“shell不可知”的解决方案。
bash
解决方案并不总是适合我(当然,OP不会有问题,因为他们用bash标记)不过,这里没有特别与bash相关的东西可能不会被真正的旧Berne外壳支持,但是任何合理的POSIX都应该处理这个问题,我相信。很酷。感谢更多的信息,我必须在 TCSH >下检查。总是有好几种方法来完成给定的任务。您可以考虑添加Perl PE版本,它没有所有的THO。se反斜杠。只需使用regex technique.perl-ne为OP提供一些选项,在本例中为@claytonstanley,但已完成。感谢您的建议。
sed -n 's/^.* \([0-9.]\+\) seconds.*$/\1/p'  <<<"Speed : 1624.127424 Kib/s in 9.410000 seconds" 
perl -lne 'print $1 if /([0-9.]+) seconds/'  <<<"Speed : 1624.127424 Kib/s in 9.410000 seconds" 
$ perl -lane 'print $F[5] data.txt'
9.410000