在Bash中将命令的输出读入数组

时间:2012-07-11 06:08:24

标签: arrays bash

我需要将脚本中的命令输出读入数组。该命令例如是:

ps aux | grep | grep | x 

它会逐行输出:

10
20
30

我需要将命令输出中的值读入数组,然后如果数组的大小小于3,我会做一些工作。

3 个答案:

答案 0 :(得分:84)

如果命令的输出包含空格(相当频繁)或者像*?[...]这样的全局字符,其他答案将会中断。

要在数组中获取命令的输出,基本上有两种方法:

  1. 使用Bash≥4使用mapfile - 效率最高:

    mapfile -t my_array < <( my_command )
    
  2. 否则,循环读取输出(较慢但安全):

    my_array=()
    while IFS= read -r line; do
        my_array+=( "$line" )
    done < <( my_command )
    
  3. 您可能会看到很多这样的内容:

    my_array=( $( my_command) )
    

    但不要使用它!看看它是如何破碎的:

    $ # this is the command used to test:
    $ echo "one two"; echo "three four"
    one two
    three four
    $ my_array=( $( echo "one two"; echo "three four" ) )
    $ declare -p my_array
    declare -a my_array='([0]="one" [1]="two" [2]="three" [3]="four")'
    $ # Not good! now look:
    $ mapfile -t my_array < <(echo "one two"; echo "three four")
    $ declare -p my_array
    declare -a my_array='([0]="one two" [1]="three four")'
    $ # Good!
    

    然后有些人会建议使用IFS=$'\n'来解决此问题:

    $ IFS=$'\n'
    $ my_array=( $(echo "one two"; echo "three four") )
    $ declare -p my_array
    declare -a my_array='([0]="one two" [1]="three four")'
    $ # It works!
    

    但现在让我们使用另一个命令:

    $ echo "* one two"; echo "[three four]"
    * one two
    [three four]
    $ IFS=$'\n'
    $ my_array=( $(echo "* one two"; echo "[three four]") )
    $ declare -p my_array
    declare -a my_array='([0]="* one two" [1]="t")'
    $ # What?
    

    那是因为我在当前目录中有一个名为t的文件...并且此文件名由 glob [three four]匹配...此时有些人会建议使用{ {1}}禁用通配:但请注意:您必须更改set -f并使用IFS才能修复损坏的技术(您甚至无法修复它)!当我这样做时,我们真的正在与对抗,而不是使用shell

    set -f

    这里我们正在使用shell!

答案 1 :(得分:73)

您可以使用

my_array=( $(<command>) )

将命令<command>的输出存储到数组my_array

您可以使用

访问该数组的长度
my_array_length=${#my_array[@]}

现在长度存储在my_array_length

答案 2 :(得分:8)

想象一下,您要将文件和目录名称(在当前文件夹下)放入数组并计算其项目。脚本就像;

$psversiontable

或者,您可以通过添加以下脚本来迭代此数组:

my_array=( `ls` )
my_array_length=${#my_array[@]}
echo $my_array_length