Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何为返回空白项的循环下标_Bash - Fatal编程技术网

Bash 如何为返回空白项的循环下标

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 &

这可以打印两行:

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 "'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