I need to read the output of the command in my script into an array. The command is for example:
我需要将脚本中命令的输出读入一个数组。例如,命令是:
ps aux | grep | grep | x
and it gives the output line by line like this;
它的输出线是这样的;
10
20
30
I need to read the values from the command output to array and then I will do some work if the size of array<3.
我需要从命令输出读取到数组的值,然后如果数组的大小为<3,我将做一些工作。
3 个解决方案
#1
53
You can use
您可以使用
my_array=( $(<command>) )
to store the output of command <command>
into the array my_array
.
将命令
You can access the length of that array using
您可以使用
my_array_length=${#my_array[@]}
Now the length is stored in my_array_length
.
现在长度存储在my_array_length中。
#2
35
The other answers will break if output of command contains spaces (which is rather frequent) or glob characters like *
, ?
, [...]
.
如果命令的输出包含空格(非常频繁)或诸如*、?、[…]等通配符,则其他答案将失效。
To get the output of a command in an array there are essentially 2 ways:
要在数组中获取命令的输出,基本上有两种方法:
-
With Bash≥4 use
mapfile
—it's the most efficient:使用Bash≥4 mapfile-it最有效:
mapfile -t my_array < <( my_command )
-
Otherwise, a loop reading the output (slower, but safe):
否则,读取输出的循环(较慢,但安全):
my_array=() while IFS= read -r line; do my_array+=( "$line" ) done < <( my_command )
You'll probably see a lot of this:
你可能会看到很多这样的东西:
my_array=( $( my_command) )
But don't use it! Look how it's broken:
但不要使用它!看它坏了:
$ # 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!
Then some people would recommend using IFS=$'\n'
to fix this:
然后一些人建议使用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!
But now let's use another command:
现在让我们使用另一个命令:
$ 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?
That's because I have a file called t
in the current directory… and this filename is matched by the glob [three four]
… at this point some people would recommend using set -f
to disable globbing: but look at it: you have to change IFS
and use set -f
to be able to fix a broken technique (and you're not even fixing it really)! when doing that we're really fighting against the shell, not working with the shell.
那是因为我有一个名为t的文件在当前目录中,这个文件名匹配通配符匹配操作符(三四个)……在这一点上有些人会建议使用- f设置为禁用globbing:但是看:你必须改变IFS和使用- f能够修复一个破碎的技术(甚至你不修理它真的)!当这样做的时候,我们实际上是在和壳战斗,而不是和壳战斗。
$ mapfile -t my_array < <( echo "* one two"; echo "[three four]")
$ declare -p my_array
declare -a my_array='([0]="* one two" [1]="[three four]")'
here we're working with the shell!
这是我们用壳做的!
#3
4
Imagine that you are going to put the files and directory names (under the current folder) to an array and count its items. The script would be like;
假设您要将文件和目录名(在当前文件夹下)放在一个数组中,并对其项进行计数。剧本是这样的;
my_array=( `ls` )
my_array_length=${#my_array[@]}
echo $my_array_length
Or, you can iterate over this array by adding the following script:
或者,您可以通过添加以下脚本对该数组进行迭代:
for element in "${my_array[@]}"
do
echo "${element}"
done
#1
53
You can use
您可以使用
my_array=( $(<command>) )
to store the output of command <command>
into the array my_array
.
将命令
You can access the length of that array using
您可以使用
my_array_length=${#my_array[@]}
Now the length is stored in my_array_length
.
现在长度存储在my_array_length中。
#2
35
The other answers will break if output of command contains spaces (which is rather frequent) or glob characters like *
, ?
, [...]
.
如果命令的输出包含空格(非常频繁)或诸如*、?、[…]等通配符,则其他答案将失效。
To get the output of a command in an array there are essentially 2 ways:
要在数组中获取命令的输出,基本上有两种方法:
-
With Bash≥4 use
mapfile
—it's the most efficient:使用Bash≥4 mapfile-it最有效:
mapfile -t my_array < <( my_command )
-
Otherwise, a loop reading the output (slower, but safe):
否则,读取输出的循环(较慢,但安全):
my_array=() while IFS= read -r line; do my_array+=( "$line" ) done < <( my_command )
You'll probably see a lot of this:
你可能会看到很多这样的东西:
my_array=( $( my_command) )
But don't use it! Look how it's broken:
但不要使用它!看它坏了:
$ # 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!
Then some people would recommend using IFS=$'\n'
to fix this:
然后一些人建议使用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!
But now let's use another command:
现在让我们使用另一个命令:
$ 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?
That's because I have a file called t
in the current directory… and this filename is matched by the glob [three four]
… at this point some people would recommend using set -f
to disable globbing: but look at it: you have to change IFS
and use set -f
to be able to fix a broken technique (and you're not even fixing it really)! when doing that we're really fighting against the shell, not working with the shell.
那是因为我有一个名为t的文件在当前目录中,这个文件名匹配通配符匹配操作符(三四个)……在这一点上有些人会建议使用- f设置为禁用globbing:但是看:你必须改变IFS和使用- f能够修复一个破碎的技术(甚至你不修理它真的)!当这样做的时候,我们实际上是在和壳战斗,而不是和壳战斗。
$ mapfile -t my_array < <( echo "* one two"; echo "[three four]")
$ declare -p my_array
declare -a my_array='([0]="* one two" [1]="[three four]")'
here we're working with the shell!
这是我们用壳做的!
#3
4
Imagine that you are going to put the files and directory names (under the current folder) to an array and count its items. The script would be like;
假设您要将文件和目录名(在当前文件夹下)放在一个数组中,并对其项进行计数。剧本是这样的;
my_array=( `ls` )
my_array_length=${#my_array[@]}
echo $my_array_length
Or, you can iterate over this array by adding the following script:
或者,您可以通过添加以下脚本对该数组进行迭代:
for element in "${my_array[@]}"
do
echo "${element}"
done