Bash 声明性地定义要循环的列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10687313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash declaratively defining a list to loop on
提问by Adam Gent
In bash I frequently make scripts where I loop over a list of strings that I define.
在 bash 中,我经常在脚本中循环我定义的字符串列表。
e.g.
例如
for a in 1 2 3 4; do echo $a; done
However I would like to define the list (before the loop to keep it clean) so that it contains spaces and with out a separate file:
但是,我想定义列表(在循环之前以保持清洁),以便它包含空格并且没有单独的文件:
e.g. (BUT THIS WILL NOT WORK)
例如(但这行不通)
read -r VAR <<HERE
list item 1
list item 2
list item 3
...
HERE
for a in $VAR; do echo $a; done
The expected output above (I would like):
上面的预期输出(我想要):
list item 1
list item 2
list item 3
etc...
But you will get:
但你会得到:
list
item
1
I could use arrays but I would have to index each element in the array (EDIT read answers below as you can append to arrays.. I did not know you could).
我可以使用数组,但我必须索引数组中的每个元素(编辑阅读下面的答案,因为您可以附加到数组..我不知道您可以)。
How do others declaratively define lists in bash with out using separate files?
其他人如何在 bash 中声明性地定义列表而不使用单独的文件?
Sorry I forgot to mention I want to define the list at the top of the filebefore the for loop logic
抱歉我忘了提到我想在 for 循环逻辑之前定义文件顶部的列表
回答by choroba
You can use the "HERE Document" like this:
您可以像这样使用“HERE 文档”:
while read a ; do echo "Line: $a" ; done <<HERE
123 ab c
def aldkfgjlaskdjf lkajsdlfkjlasdjf
asl;kdfj ;laksjdf;lkj asd;lf sdpf -aa8
HERE
回答by chepner
Arrays aren't so hard to use:
数组并不难使用:
readarray <<HERE
this is my first line
this is my second line
this is my third line
HERE
# Pre bash-4, you would need to build the array more explicity
# Just like readarray defaults to MAPFILE, so read defaults to REPLY
# Tip o' the hat to Dennis Williamson for pointing out that arrays
# are easily appended to.
# while read ; do
# MAPFILE+=("$REPLY")
# done
for a in "${MAPFILE[@]}"; do
echo "$a"
done
This has the added benefit of allowing each list item to contain spaces, should you have that need.
如果您有需要,这具有允许每个列表项包含空格的额外好处。
回答by Paused until further notice.
while read -r line
do
var+=$line$'\n'
done <<EOF
foo bar
baz qux
EOF
while read -r line
do
echo "[$line]"
done <<<"$var"
Why would you need to index arrays? You can append to arrays and iterate over them without using indices.
为什么需要索引数组?您可以附加到数组并在不使用索引的情况下迭代它们。
array+=(value)
for item in "${array[@]}"
do
something with "$item"
done
回答by mVChr
There are better answers here, but you can also delimit the read on \nand temporarily change the variable to split on newlines instead of whitespace in the forloop using the IFSenvironment variable.
这里有更好的答案,但您也可以使用环境变量分隔读取\n并临时更改变量以在换行符上拆分而不是在for循环中使用空格IFS。
read -d \n -r VAR <<HERE
list item 1
list item 2
list item 3
HERE
IFS_BAK=$IFS
IFS="\n"
for a in $VAR; do echo $a; done
IFS=$IFS_BAK
回答by Dr. Jan-Philip Gehrcke
When it's fine for you to use a whileloop instead of a forloop, you can make use of the while readconstruct and a "here document":
当您可以使用while循环而不是for循环时,您可以使用while read构造和“此处文档”:
#!/bin/bash
while read LINE; do
echo "${LINE}"
done << EOF
list item 1
list item 2
list item 3
EOF

