如何删除字符串输出的前两个单词

5

我希望在输出的字符串中去掉前两个单词,这个字符串也在另一个字符串中。

我的现状:

for servers in `ls /data/field`    
do    
  string=`cat /data/field/$servers/time`

这会发送以下文本:
00:00 down server

我希望能只显示 "server",并移除"00:00 down"。
我已经尝试使用cut -d ' ' -f2- $string,但这样做只会移除命令搜索的目录。
有任何想法吗?
4个回答

10
请正确地做事:
for servers in /data/field/*; do
    string=$(cut -d" "  -f3- /data/field/$servers/time)
    echo "$string"
done
  • 在2014年,backticks已经被弃用,建议使用$( )形式。
  • 不要解析ls的输出结果,而是像我一样使用glob,比如data/field/*

请查看http://mywiki.wooledge.org/BashFAQ获取更多相关主题。


我必须承认,我也有同样的坏习惯,所以我开始寻找为什么在这种情况下不应该使用ls的原因。所以感谢您提供的链接+1。无论如何,常见问题解答非常大,为了节省其他人的时间,为什么不应该使用ls,请参见:http://mywiki.wooledge.org/ParsingLs - Bitdiot

6

使用-d选项将分隔符设置为空格。

$ echo 00:00 down server | cut -d" "  -f3-
server

注意:字段编号从1开始计数,而不是从0开始计数。

来自man页面

  -d, --delimiter=DELIM
              use DELIM instead of TAB for field delimiter

   N-     from N'th byte, character or field, to end of line

更多测试

$ echo 00:00 down server hello world| cut -d" "  -f3-
server hello world
for 循环可以使用通配符(globbing)来遍历文件,因此我会写类似这样的代码:
for servers in /data/field*
do    
  string=`cut -d" "  -f3- /data/field/$servers/time`
...
...

只要单词之间用正好一个空格分隔,这将起作用。 - Otheus

2
您也可以使用sed:
sed 's/^.* * //'

0
对于所给的例子,我更喜欢使用cut。但是针对问题的一般情况来说,上述答案都存在一些缺点。例如,当你不知道单词之间有多少空格(cut),或它们是否以空格开头(sed, cut),或者难以在管道中使用(shell for-loop)。下面是一个快速、高效且易于记忆的Perl示例:
 | perl -pe 's/^\s*(\S+\s+){2}//'

Perl的-p操作类似于sed。也就是说,它一次读取一行输入,像-n一样,并在完成工作后再次打印该行。 -e启动基于命令行的脚本。该脚本只是一个一行的替换s///表达式;用右侧的字符串替换左侧匹配的正则表达式。在这种情况下,右侧为空,因此我们只是剪切左侧找到的表达式。

正则表达式特定于Perl(以及所有PLRE衍生物,例如Python、Ruby和Javascript),使用\s匹配空格,使用\S匹配非空格。因此,\S+\s+的组合匹配一个单词及其空格。我们将该子表达式与(...)分组,然后告诉sed连续匹配2个该组表达式,其中n是可选的,m是2。前导的\s*表示修剪前导空格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接