在 Bash 中循环遍历字符串数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8880603/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:29:40  来源:igfitidea点击:

Loop through an array of strings in Bash?

arraysbashshell

提问by Mo.

I want to write a script that loops through 15 strings (array possibly?) Is that possible?

我想编写一个循环遍历 15 个字符串(可能是数组?)的脚本,这可能吗?

Something like:

就像是:

for databaseName in listOfNames
then
  # Do something
end

回答by anubhava

You can use it like this:

你可以这样使用它:

## declare an array variable
declare -a arr=("element1" "element2" "element3")

## now loop through the above array
for i in "${arr[@]}"
do
   echo "$i"
   # or do whatever with individual element of the array
done

# You can access them using echo "${arr[0]}", "${arr[1]}" also

Also works for multi-line array declaration

也适用于多行数组声明

declare -a arr=("element1" 
                "element2" "element3"
                "element4"
                )

回答by 4ndrew

That is possible, of course.

当然,这是可能的。

for databaseName in a b c d e f; do
  # do something like: echo $databaseName
done 

See Bash Loops for, while and untilfor details.

有关详细信息请参阅Bash 循环 for、while 和 until

回答by caktux

None of those answers include a counter...

这些答案都不包括计数器......

#!/bin/bash
## declare an array variable
declare -a array=("one" "two" "three")

# get length of an array
arraylength=${#array[@]}

# use for loop to read all values and indexes
for (( i=1; i<${arraylength}+1; i++ ));
do
  echo $i " / " ${arraylength} " : " ${array[$i-1]}
done

Output:

输出:

1  /  3  :  one
2  /  3  :  two
3  /  3  :  three

回答by FireInTheSky

Yes

是的

for Item in Item1 Item2 Item3 Item4 ;
  do
    echo $Item
  done

Output:

输出:

Item1
Item2
Item3
Item4

To preserve spaces; single or double quote list entries and double quote list expansions.

保留空间;单引号或双引号列表条目和双引号列表扩展。

for Item in 'Item 1' 'Item 2' 'Item 3' 'Item 4' ;
  do
    echo "$Item"
  done

Output:

输出:

Item 1
Item 2
Item 3
Item 4

To make list over multiple lines

制作多行列表

for Item in Item1 \
            Item2 \
            Item3 \
            Item4
  do
    echo $Item
  done

Output:

输出:

Item1
Item2
Item3
Item4


Simple list variable


简单列表变量

List=( Item1 Item2 Item3 )

or

或者

List=(
      Item1 
      Item2 
      Item3
     )

Display the list variable:

显示列表变量:

echo ${List[*]}

Output:

输出:

Item1 Item2 Item3

Loop through the list:

循环遍历列表:

for Item in ${List[*]} 
  do
    echo $Item 
  done

Output:

输出:

Item1
Item2
Item3

Create a function to go through a list:

创建一个函数来遍历列表:

Loop(){
  for item in ${*} ; 
    do 
      echo ${item} 
    done
}
Loop ${List[*]}

Using the declare keyword (command) to create the list, which is technically called an array:

使用declare关键字(命令)创建列表,技术上称为数组:

declare -a List=(
                 "element 1" 
                 "element 2" 
                 "element 3"
                )
for entry in "${List[@]}"
   do
     echo "$entry"
   done

Output:

输出:

element 1
element 2
element 3

Creating an associative array. A dictionary:

创建关联数组。一本字典:

declare -A continent

continent[Vietnam]=Asia
continent[France]=Europe
continent[Argentina]=America

for item in "${!continent[@]}"; 
  do
    printf "$item is in ${continent[$item]} \n"
  done

Output:

输出:

 Argentina is in America
 Vietnam is in Asia
 France is in Europe

CVS variables or files in to a list.
Changing the internal field separator from a space, to what ever you want.
In the example below it is changed to a comma

将 CVS 变量或文件放入一个列表中
将内部字段分隔符从空格更改为您想要的任何内容。
在下面的示例中,它更改为逗号

List="Item 1,Item 2,Item 3"
Backup_of_internal_field_separator=$IFS
IFS=,
for item in $List; 
  do
    echo $item
  done
IFS=$Backup_of_internal_field_separator

Output:

输出:

Item 1
Item 2
Item 3

If need to number them:

如果需要给它们编号:

` 

this is called a back tick. Put the command inside back ticks.

这称为回勾。将命令放在后面的刻度内。

`commend` 

It is next to the number one on your keyboard and or above the tab key. On a standard american english language keyboard.

它位于键盘上的数字旁边或 Tab 键上方。在标准的美式英语键盘上。

List=()
Start_count=0
Step_count=0.1
Stop_count=1
for Item in `seq $Start_count $Step_count $Stop_count`
    do 
       List+=(Item_$Item)
    done
for Item in ${List[*]}
    do 
        echo $Item
    done

Output is:

输出是:

Item_0.0
Item_0.1
Item_0.2
Item_0.3
Item_0.4
Item_0.5
Item_0.6
Item_0.7
Item_0.8
Item_0.9
Item_1.0

Becoming more familiar with bashes behavior:

更加熟悉 bashes 行为:

Create a list in a file

在文件中创建列表

cat <<EOF> List_entries.txt
Item1
Item 2 
'Item 3'
"Item 4"
Item 7 : *
"Item 6 : * "
"Item 6 : *"
Item 8 : $PWD
'Item 8 : $PWD'
"Item 9 : $PWD"
EOF

Read the list file in to a list and display

将列表文件读入列表并显示

List=$(cat List_entries.txt)
echo $List
echo '$List'
echo "$List"
echo ${List[*]}
echo '${List[*]}'
echo "${List[*]}"
echo ${List[@]}
echo '${List[@]}'
echo "${List[@]}"

BASH commandline reference manual: Special meaning of certain characters or words to the shell.

BASH 命令行参考手册:某些字符或单词对 shell 的特殊含义。

回答by user2533809

In the same spirit as 4ndrew's answer:

本着与 4ndrew 的回答相同的精神:

listOfNames="RA
RB
R C
RD"

# To allow for other whitespace in the string:
# 1. add double quotes around the list variable, or
# 2. see the IFS note (under 'Side Notes')

for databaseName in "$listOfNames"   #  <-- Note: Added "" quotes.
do
  echo "$databaseName"  # (i.e. do action / processing of $databaseName here...)
done

# Outputs
# RA
# RB
# R C
# RD

B. No whitespace in the names:

B. 名称中没有空格:

listOfNames="RA
RB
R C
RD"

for databaseName in $listOfNames  # Note: No quotes
do
  echo "$databaseName"  # (i.e. do action / processing of $databaseName here...)
done

# Outputs
# RA
# RB
# R
# C
# RD

Notes

笔记

  1. In the second example, using listOfNames="RA RB R C RD"has the same output.
  1. 在第二个示例中, usinglistOfNames="RA RB R C RD"具有相同的输出。

Other ways to bring in data include:

其他引入数据的方法包括:

Read from stdin

从标准输入读取

# line delimited (each databaseName is stored on a line)
while read databaseName
do
  echo "$databaseName"  # i.e. do action / processing of $databaseName here...
done # <<< or_another_input_method_here
  1. the bash IFS"field separator to line" [1] delimiter can be specified in the script to allow other whitespace (i.e. IFS='\n', or for MacOS IFS='\r')
  2. I like the accepted answer also :) -- I've include these snippets as other helpful ways that also answer the question.
  3. Including #!/bin/bashat the top of the script file indicates the execution environment.
  4. It took me months to figure out how to code this simply :)
  1. 可以在脚本中指定bash IFS“字段分隔符到行”[ 1] 分隔符以允许其他空格(即IFS='\n',或用于 MacOS IFS='\r'
  2. 我也喜欢接受的答案 :) -- 我已经将这些片段作为其他有用的方法也可以回答这个问题。
  3. 包含#!/bin/bash在脚本文件顶部的表示执行环境。
  4. 我花了几个月的时间才弄清楚如何简单地编写代码:)

Other Sources (while read loop)

其他来源(while read loop

回答by Fizer Khan

You can use the syntax of ${arrayName[@]}

您可以使用以下语法 ${arrayName[@]}

#!/bin/bash
# declare an array called files, that contains 3 values
files=( "/etc/passwd" "/etc/group" "/etc/hosts" )
for i in "${files[@]}"
do
    echo "$i"
done

回答by Doorknob

Surprised that nobody's posted this yet -- if you need the indices of the elements while you're looping through the array, you can do this:

令人惊讶的是还没有人发布这个 - 如果您在遍历数组时需要元素的索引,您可以这样做:

arr=(foo bar baz)

for i in ${!arr[@]}
do
    echo $i "${arr[i]}"
done

Output:

输出:

0 foo
1 bar
2 baz

I find this a lot more elegant than the "traditional" for-loop style (for (( i=0; i<${#arr[@]}; i++ ))).

我发现这比“传统” for 循环样式 ( for (( i=0; i<${#arr[@]}; i++ )))优雅得多。

(${!arr[@]}and $idon't need to be quoted because they're just numbers; some would suggest quoting them anyway, but that's just personal preference.)

${!arr[@]}并且$i不需要引用,因为它们只是数字;有些人会建议无论如何引用它们,但这只是个人喜好。)

回答by Treethawat Thanawachiramate

This is also easy to read:

这也很容易阅读:

FilePath=(
    "/tmp/path1/"    #FilePath[0]
    "/tmp/path2/"    #FilePath[1]
)

#Loop
for Path in "${FilePath[@]}"
do
    echo "$Path"
done

回答by F. Hauri

Implicit array for script or functions:

脚本或函数的隐式数组:

In addition to anubhava's correct answer: If basic syntax for loop is:

除了anubhava的正确答案:如果循环的基本语法是:

for var in "${arr[@]}" ;do ...$var... ;done

there is a specialcase in bash:

bash 中有一个特殊情况:

When running a script or a function, argumentspassed at command lines will be assigned to $@array variable, you can access by $1, $2, $3, and so on.

运行脚本或函数时,在命令行传递的参数将分配给$@数组变量,您可以通过$1$2、 等访问$3

This can be populated (for test) by

这可以填充(用于测试)

set -- arg1 arg2 arg3 ...

A loopover thisarray could be written simply:

一个循环这个阵列可以简单地写成:

for item ;do
    echo "This is item: $item."
  done

Notethat the reserved work inis not present and no array name too!

请注意,保留的工作in不存在,也没有数组名称!

Sample:

样本:

set -- arg1 arg2 arg3 ...
for item ;do
    echo "This is item: $item."
  done
This is item: arg1.
This is item: arg2.
This is item: arg3.
This is item: ....

Note that this is same than

请注意,这与

for item in "$@";do
    echo "This is item: $item."
  done

Then into a script:

然后进入一个脚本

#!/bin/bash

for item ;do
    printf "Doing something with '%s'.\n" "$item"
  done

Save this in a script myscript.sh, chmod +x myscript.sh, then

将其保存在脚本myscript.shchmod +x myscript.sh,然后

./myscript.sh arg1 arg2 arg3 ...
Doing something with 'arg1'.
Doing something with 'arg2'.
Doing something with 'arg3'.
Doing something with '...'.

Same in a function:

函数中相同:

myfunc() { for item;do cat <<<"Working about '$item'."; done ; }

Then

然后

myfunc item1 tiem2 time3
Working about 'item1'.
Working about 'tiem2'.
Working about 'time3'.

回答by rashedcs

Simple way :

简单的方法:

arr=("sharlock"  "bomkesh"  "feluda" )  ##declare array

len=${#arr[*]}  # it returns the array length

#iterate with while loop
i=0
while [ $i -lt $len ]
do
    echo ${arr[$i]}
    i=$((i+1))
done


#iterate with for loop
for i in $arr
do
  echo $i
done

#iterate with splice
 echo ${arr[@]:0:3}