如何在Linux中的循环中按值打印数组值?

时间:2021-04-08 21:42:03

So my shell script look something like this:

我的shell脚本是这样的:

VAR=$(shuf -i 1-10 -n 3)
N=1
while [$N le 3 ]; do
    NUM=$VAR | awk '{print$`echo $N`}'
    #some commands that uses $NUM
    N=$(($N+1))
done

But I think awk does not work here, since

但我认为awk从那以后就不在这里工作了

echo $VAR | awk '{print$`echo $N`}'

gives me

给我

awk: cmd. line:1: {print$`echo $N`}
awk: cmd. line:1:        ^ invalid char '`' in expression
awk: cmd. line:1: {print$`echo $N`}
awk: cmd. line:1:        ^ syntax error

So I tried the following command

所以我尝试了下面的命令

 echo $VAR | awk '{print$$(echo $N)}'

This time I always see all three values, regardless of what $N was

这一次我总是看到这三个值,不管N是多少

Are there other commands I could try?

我还可以尝试其他命令吗?

1 个解决方案

#1


3  

Multiple syntax issues and anti-patterns in use! Do check your script in ShellCheck for trivial syntax issues.

  1. Variables in shell are not meant to store multi-line items. Use an array and loop over it.
  2. shell中的变量不打算存储多行项。使用数组并对其进行循环。
  3. The bash constructs are space-sensitive, a simple missed space in [$N le 3 ] needs to be written as [ $N le 3 ]
  4. bash构造对空间敏感,需要将[$N le 3]中的一个简单的丢失空间写成[$N le 3]
  5. The syntax for running commands and storing output in a variable is just wrong. The actual command substitution syntax is to use var=$(..), where the $(..) contains the commands to be run.
  6. 在变量中运行命令和存储输出的语法是错误的。实际的命令替换语法是使用var=$(..),其中$(..)包含要运行的命令。
  7. You can't run command-substitution (back-ticks or $(..)) inside awk. Remember awk is not shell. You don't need to use awk or any third party tool for iterating over an array, just use the shell internals.
  8. 您不能在awk中运行命令替换(back-ticks或$(..))。记住awk不是shell。您不需要使用awk或任何第三方工具对数组进行迭代,只需使用shell内部元素。

Since shuf prints output in new line. Use a tool mapfile/readarray to store items safely into the array, i.e.

因为shuf在新行中打印输出。使用工具mapfile/readarray将项目安全地存储到数组中,例如。

mapfile -t randomElements < <(shuf -i 1-10 -n 3)

The <() is a special construct in bash called process substitution which the output of a process (shuf in your case) appear as a temporary file to read from.

<()是bash中的一种特殊构造,称为进程替换,进程的输出(在您的例子中是shuf)作为一个要读取的临时文件出现。

We now use a loop to iterate over the elements,

现在我们使用循环遍历元素,

for ((i=0; i<"${#randomElements[@]}"; i++)); do 
    printf '%s\n' "${randomElements[i]}"
done

If by chance mapfile/readarray which should be available in bash versions 4.3 and later is not present, use the read command

如果偶然的mapfile/readarray应该在bash版本4.3中可用,并且以后不存在,请使用read命令。

while IFS= read -r line; do arr+=("$line"); done < <(shuf -i 1-10 -n 3)

and use the printing logic as usual.

并像往常一样使用打印逻辑。

#1


3  

Multiple syntax issues and anti-patterns in use! Do check your script in ShellCheck for trivial syntax issues.

  1. Variables in shell are not meant to store multi-line items. Use an array and loop over it.
  2. shell中的变量不打算存储多行项。使用数组并对其进行循环。
  3. The bash constructs are space-sensitive, a simple missed space in [$N le 3 ] needs to be written as [ $N le 3 ]
  4. bash构造对空间敏感,需要将[$N le 3]中的一个简单的丢失空间写成[$N le 3]
  5. The syntax for running commands and storing output in a variable is just wrong. The actual command substitution syntax is to use var=$(..), where the $(..) contains the commands to be run.
  6. 在变量中运行命令和存储输出的语法是错误的。实际的命令替换语法是使用var=$(..),其中$(..)包含要运行的命令。
  7. You can't run command-substitution (back-ticks or $(..)) inside awk. Remember awk is not shell. You don't need to use awk or any third party tool for iterating over an array, just use the shell internals.
  8. 您不能在awk中运行命令替换(back-ticks或$(..))。记住awk不是shell。您不需要使用awk或任何第三方工具对数组进行迭代,只需使用shell内部元素。

Since shuf prints output in new line. Use a tool mapfile/readarray to store items safely into the array, i.e.

因为shuf在新行中打印输出。使用工具mapfile/readarray将项目安全地存储到数组中,例如。

mapfile -t randomElements < <(shuf -i 1-10 -n 3)

The <() is a special construct in bash called process substitution which the output of a process (shuf in your case) appear as a temporary file to read from.

<()是bash中的一种特殊构造,称为进程替换,进程的输出(在您的例子中是shuf)作为一个要读取的临时文件出现。

We now use a loop to iterate over the elements,

现在我们使用循环遍历元素,

for ((i=0; i<"${#randomElements[@]}"; i++)); do 
    printf '%s\n' "${randomElements[i]}"
done

If by chance mapfile/readarray which should be available in bash versions 4.3 and later is not present, use the read command

如果偶然的mapfile/readarray应该在bash版本4.3中可用,并且以后不存在,请使用read命令。

while IFS= read -r line; do arr+=("$line"); done < <(shuf -i 1-10 -n 3)

and use the printing logic as usual.

并像往常一样使用打印逻辑。