将一个变量中的特定行分配给另一个变量

将一个变量中的特定行分配给另一个变量

我想将一个特定的行从一个变量转移到另一个变量。我尝试了这个,但它不起作用:

c="1.apple
2.banna
3.peach"

read "Please choose fruit [1-3]:" t

a=$c | awk "NR==$t"
echo "You choose: $a"

我的错误是什么?

答案1

使用这里字符串重定向<<<和...一起命令替换$()并且不要忘记在变量两边加上双引号:

a=$(awk "NR==$t" <<< "$c")

答案2

首先:

read "Please choose fruit [1-3]:" t

...不管用。看起来您正在尝试向 shellbuiltin 提供提示字符串read,但read将其第一个参数解释为变量的名称,以分配从 stdin 读取的行的值,除非它被赋予选项。

read -p "Please choose fruit [1-3]:" t

...是许多 shell 中支持的选项,并且可能更接近您想要执行的操作。

也就是说,您可能不应该在单分隔赋值中堆叠多个值,除非您之前已经确定了将其拆分的方法。当你这样做时:

var=' some list of things '

shell 最终会将其解析为:

\0 some list of things \0

...并将单个名称分配给单个值。许多 shell 提供更高级的分隔形式 - 例如命名数组 - 但所有 POSIX shell 为每个函数上下文提供至少一个易于定义的数组 - $@shell 数组。提供命名数组的各种实现通常$@也模仿其命名数组的 shell 数组行为。

因此,您可以这样做,而不是像您那样将所有这些单独的值分配给单个字符串:

set apple banana peach

您可以通过按数字单独寻址每个单独的值来见证其效果,例如:

printf %s\\n "$1"

...打印:

apple

注意 - 如果您要使用大于 9 的值,最好将引用括在大括号中,例如"${10}"

您可以像这样解决不同字符串的数量"$#"

printf %d\\n "$#"

...打印...

3

您可以在单独的字符串列表中解决其中的很多问题,例如:

printf %s\\n "$@"

...打印:

apple
banana
peach

...或者作为单个连接字符串,例如:

printf %s\\n "$*"

...其中单独的数组值字符串连接在 shell 变量中包含的第一个字符上$IFS。因此,如果数组中的每个字符串都有默认$IFS值,则它们之间将用单个字符串连接到下一个字符串。例如,上面的命令打印:<space><tab><newline><space>

apple banana peach

...但是如果我这样做:

IFS='fruit sucks'; printf %s\\n "$*"

...它打印:

applefbananafpeach

大多数实现命名数组扩展的 shell 都使用类似的语法,但寻址数组的各种方法必须与名称相关联。数组赋值通常如下所示:

array=( apple banana peach )

...或者...

array[0]=apple array[1]=banana array[2]=peach

"$1"与, "$#", "$@",相比"$*",命名数组通常会像"${array[1]}", "${#array[@]}",一样工作"${array[@]}",并且前面提到的和"${array[*]}"之间的关系仍然适用。"$*""$IFS""${array[*]}"

一旦你正确地界定了你的价值观,你的问题就会变得更容易处理:

set apple banana peach; n=0
{   for a do printf "$((n+=1)).:\t%s\n" "$a"; done
    printf "Please choose fruit [1-$#]: "; read t
} <>/dev/tty >&0 &&
[ "0$((!${#t}))" -lt "0${t##*[!0-9]*}" ] &&
eval 'printf "You choose: %s\n" "${'"$t"}\"

有些人可能会嘲笑上面的使用eval,但它在这里的使用并不比许多人希望的安全"${array[$t]}" (这是使用命名数组执行此操作的一种方法)因为意味着在第一次将其解析为字符串后,将对其"${array[$t]}"进行第二次评估。$t无需像我上面那样对其进行测试,以确保它至少包含 1 并且只包含数字并且大于 0(或者 shell 实现的最小命名数组索引可能是什么)任何一种情况都可能导致意想不到的结果。

相关内容