Bash 如何为返回空白项的循环下标
这可以打印两行: a b c d 这将打印四行:Bash 如何为返回空白项的循环下标,bash,Bash,这可以打印两行: a b c d 这将打印四行: for i in $(echo "'a b' 'c d'");do echo $i;done 我尝试使用带有eval的数组。这很有效 'a b' 'c d' eval数组=($(echo“'ab''cd')) 对于((i=0;i我假设您有一些变量被构造为一个空格分隔的列表,并且您的项可能包含空格 正如您所看到的,在bash中进行迭代非常困难 如果您对变量生成有任何控制,请考虑如下: eval array=($(echo &
for i in $(echo "'a b' 'c d'");do echo $i;done
我尝试使用带有eval
的数组。这很有效
'a
b'
'c
d'
eval数组=($(echo“'ab''cd'))
对于((i=0;i我假设您有一些变量被构造为一个空格分隔的列表,并且您的项可能包含空格
正如您所看到的,在bash中进行迭代非常困难
如果您对变量生成有任何控制,请考虑如下:
eval array=($(echo "'a b' 'c d'")
for ((i=0;i<${#array[@]};i++));do echo ${array[$i]};done
如果您无法控制变量的创建,您仍然可以使其不那么复杂:
lines="a b
c d"
( IFS=$'\n' ; for i in $lines ; do echo $i ; done ; )
更新——如下文所述,以下是一些解释:
第一种解决方案:
- 来自man bash:
IFS
内部字段分隔符,用于在展开后拆分单词,并使用read-builtin命令将行拆分为单词。默认值为“`”
- 还要注意分配给IFS的方式有些复杂:
IFS=$'\n'
- 这里我们使用
(
…)
将IFS的作用域封装在一个子外壳中。如果您不关心IFS的值是否会更改,或者如果您设计了其他方法来恢复其原始值,例如保存的IFS=$IFS;…;IFS=$saved\U IFS
第二种解决方案:
- 我们使用
eval array=($(echo“'ab”“cd'))
而不是array=('ab”“cd')
,因为当我们使用myvar=“'ab”“cd'”
(或我尝试过的任何其他组合)array=($myvar)
不会做正确的事情(带引号或不带引号),但eval array=($(echo$myvar))
将计算为数组=('ab'cd')
- 请注意
“${array[@]}”
和“${array[*]}”
之间的区别;它类似于“$@”和“$*”(同样来自man bash)之间的区别:
*从一开始展开到位置参数。当展开发生在双引号内时,它将展开到一个单词,每个参数的值由IFS特殊变量的第一个字符分隔。即,$*”相当于“$1c$2c…”,其中c是IFS变量值的第一个字符。如果未设置IFS,则参数之间用空格分隔。如果IFS为null,则参数之间的连接不使用分隔符
@从一开始展开到位置参数。当展开发生在双引号内时,每个参数展开到一个单独的字。即,$@相当于“$1”$2…如果双引号展开发生在单词内,则第一个参数的展开与原始单词的开头部分连接,最后一个参数的展开与原始单词的最后一部分连接。如果没有位置参数,“$@”和“$@展开为零(即,它们被删除)
不清楚您为什么认为需要在此处进行eval
eval array=($(echo "'a b' 'c d'"))
for i in "${array[@]}" ; do echo $i ; done
您想做什么,即输入中有什么,输出应该是什么?混用eval
和各种嵌套引用通常是错误的方法。@鲁本斯否,如果不使用eval.array将有四项。您可以尝试,这是因为bash parsestrategy@chepner我有一个更新问题,你现在可以看到输出了。为什么对我来说有什么错呢?
?而且,这个例子显然是人为的,所以它可以告诉你为什么你觉得有必要这么做。很酷。但是我不理解第一个代码。如果是什么意思?请你解释一下?我有谷歌高级bash-script。看起来如果是最好的选择,你不理解我的情况。请看@Chen Levy的回答。我不知道,因为你还没有解释它。如果你实际上是用eval array=($(echo“'ab'cd'))
硬编码数组值,不要:array=('ab'cd'))
更清楚。如果这只是一个生成元素包含空格的数组的示例,那么我的解决方案就可以了。或者,您真正的问题是如何处理由您的echo
生成的表单的单个字符串,该字符串作为外部程序的输出接收?
eval array=($(echo "'a b' 'c d'"))
for i in "${array[@]}" ; do echo $i ; done
array=('a b' 'c d')
for line in "${array[@]}"; do
echo "$line"
done