作为一个非常新的Linux用户,我从未(真的)使用诸如sed和awk (或任何其他工具)等工具来解析文本。我想从
速度: 1624.127424基布/秒,9.410000秒
以秒为单位的时间值,就在seconds单词之前,
我应该查一下这个工具吗?
发布于 2012-09-09 20:00:41
您可以使用许多工具,但是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)感兴趣。
也有其他的方法,但这两种方式似乎是直截了当的,并首先出现在脑海中。
发布于 2012-09-09 20:35:23
或者,如果您不知道字符串中的确切位置,但知道它在单词“秒”之前,则可以使用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匹配一个或多个数字或句点,后面跟着空格和单词“秒”。将反斜杠括号放在模式的一部分周围,会导致与模式的这一部分相匹配的实际字符串保存在变量中供以后使用;因此,\([0-9.]\+\) seconds捕获所需的数字。
因为我们只想打印这个值,所以我们把它放在^.*和.*$之间,前者匹配“从行的开头开始的所有内容”,后者匹配“所有的东西直到行的末尾”。这样整条线就会被替换。然而,由于.*是贪婪的,如果我们把它放在模式的前面,它会吞噬掉我们不想要的最后一个数字。将数字之前的空格添加到模式中可以防止这种情况发生。
我们用什么来代替这条线?使用\1,它是在(第一对)反斜杠-括号之间匹配模式部分的字符串。
编辑以添加:
问题中没有列出Perl,但与上面的sed方法类似的方法是:
perl -lne 'print $1 if /([0-9.]+) seconds/' <<<"Speed : 1624.127424 Kib/s in 9.410000 seconds" 发布于 2012-09-09 20:10:07
如果变量中只有一个字符串,则可以使用shell本身。如果您知道这是第六个字段(就像@Levon的awk解决方案假设的那样),您可以这样做:
set -- $variable
seconds=$6或者,如果您知道单词后面跟着单词seconds,则可以使用字符串替换;
prefix=${variable%\ seconds*}
seconds=${prefix##*\ }(临时变量包含在空格后带有任何内容的原始变量,“秒”被修剪掉。我们同样地从一开始就把所有的东西都整理到最后一个空间。)
不要低估壳,它是相当多才多艺的,尽管有时古怪。
https://stackoverflow.com/questions/12342451
复制相似问题