命令行:从输出中提取子字符串

kry*_*tah 29 linux bash command-line

假设我运行命令 SayStuff

$ SayStuff
Run Code Online (Sandbox Code Playgroud)

输出是

Watermelons and cucumbers
Run Code Online (Sandbox Code Playgroud)

现在。假设我想cucumbers从输出中提取子字符串并将其通过管道传输到某些内容中。
我以编程方式处理这个问题的方法是通过分隔符Space将输出拆分为一个数组,并通过ArrayName[2]. 我对 shell 脚本相当陌生,并且只成功地挖掘了半神秘的cut例子,没有一个是有意义的。

有任何想法吗?

slh*_*hck 36

$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3
cucumbers
Run Code Online (Sandbox Code Playgroud)

-d ' '告诉cut拆就空间。-f 3选择第三列。

您还可以使用awk, 它已经根据空间进行拆分并使列可用为$1, $2, ...

$ echo "Watermelons and cucumbers" | awk '{ print $3 }'
cucumbers
Run Code Online (Sandbox Code Playgroud)


ter*_*don 16

我可能会使用@slhck 已经提供的选项之一,但这里还有一些方法可以做到这一点:

  1. 使用数组,就像使用任何其他语言一样:

    $ foo=( $(SayStuff) ) 
    $ echo ${foo[2]}
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)

    var=()声明了一个阵列,$(command)保存命令的输出。因此,foo=( $(SayStuff) )将 的输出存储SayStuff到数组中foo,然后echo是第三个元素${foo[2]}

  2. sed

    $ SayStuff | sed 's/.* \(.*\)/\1/'
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)

    sed命令将s///用最后一个词替换 ( ) 所有内容。正则表达式匹配直到空格 ( .*) 的任何内容,它将匹配直到最后一个空格的所有内容,然后捕获最后一个单词(\(.*\)。由于该词已被捕获,我们可以将其称为\1

    一个更简单的版本:

    $ SayStuff | sed 's/.* //'
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)
  3. 猛击

    $ foo=$(SayStuff); echo ${foo##* } 
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)

    这使用了 bash 的字符串操作能力,请参阅此处了解更多详细信息。

  4. 更多 bash

    $ SayStuff | while read a b c; do echo $c; done
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)
  5. Perl,当然,有很多方法可以做到这一点:

    $ SayStuff | perl -lane 'print $F[$#F]'
    cucumber
    
    Run Code Online (Sandbox Code Playgroud)

    -a品牌perl表现得像awk,分割线的空白,并保存到数组@F。然后我们打印@F($#F中的元素数@F)的最后一个元素。该-l告诉Perl新行添加到每个print说法,-n它应该处理由线STDIN行,-e它应该运行在命令行给出的脚本。

    $ SayStuff | perl -pe 's/.* //'
    cucumber
    
    Run Code Online (Sandbox Code Playgroud)

    上面已经解释了这些选项,我们只是删除所有内容直到最后一个空格并打印 ( -p)。

    $ perl -le 'print $ARGV[$#ARGV]' $(SayStuff)
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)

    这里我们Watermelons and cucumbers作为参数传递,perl 将保存在@ARG数组中,因此,我们打印@ARG.

  6. 诡计。这个sed用于将空格转换为换行符,然后tail仅打印最后一行。

    $ SayStuff | sed 's/ /\n/g' | tail -n 1
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)
  7. grep 和正则表达式,使用-o它只打印匹配的字符串。

    $ SayStuff | grep -Po '\w+$' 
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)
  8. 作弊

    $ SayStuff | grep -o cucumbers
    cucumbers
    
    Run Code Online (Sandbox Code Playgroud)