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

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

类似:

for databaseName in listOfNamesthen# Do somethingend
1757358 次浏览

这当然是可能的。

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

详情见Bash循环为,而直到

你可以像这样使用它:

## declare an array variabledeclare -a arr=("element1" "element2" "element3")
## now loop through the above arrayfor i in "${arr[@]}"doecho "$i"# or do whatever with individual element of the arraydone
# You can access them using echo "${arr[0]}", "${arr[1]}" also

也适用于多行数组声明

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

声明数组不适用于Korn shell。对Korn shell使用以下示例:

promote_sla_chk_lst="cdi xlob"
set -A promote_arry $promote_sla_chk_lst
for i in ${promote_arry[*]};doecho $idone

试试这个。它是工作和测试。

for k in "${array[@]}"doecho $kdone
# For accessing with the echo command: echo ${array[0]}, ${array[1]}

在同样的精神,作为4n的回答:

listOfNames="RARBR CRD"
# 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.doecho "$databaseName"  # (i.e. do action / processing of $databaseName here...)done
# Outputs# RA# RB# R C# RD

B.名称中没有空格:

listOfNames="RARBR CRD"
for databaseName in $listOfNames  # Note: No quotesdoecho "$databaseName"  # (i.e. do action / processing of $databaseName here...)done
# Outputs# RA# RB# R# C# RD

备注

  1. 在第二个示例中,使用listOfNames="RA RB R C RD"具有相同的输出。

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

从stdin读取

# line delimited (each databaseName is stored on a line)while read databaseNamedoecho "$databaseName"  # i.e. do action / processing of $databaseName here...done # <<< or_another_input_method_here
  1. bashIFS“字段分隔符到行”[1]分隔符可以在脚本中指定以允许其他空格(即IFS='\n'或MacOSIFS='\r'
  2. 我也喜欢接受的答案 :) -- 我已经将这些片段作为回答问题的其他有用方法。
  3. 包括在脚本文件顶部的#!/bin/bash表示执行环境。
  4. 我花了几个月的时间才弄清楚如何简单地编写代码:)

其他来源(同时读取循环

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

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

这些答案都不包括反…

#!/bin/bash## declare an array variabledeclare -a array=("one" "two" "three")
# get length of an arrayarraylength=${#array[@]}
# use for loop to read all values and indexesfor (( i=0; i<${arraylength}; i++ ));doecho "index: $i, value: ${array[$i]}"done

输出:

index: 0, value: oneindex: 1, value: twoindex: 2, value: three

如果您使用的是Korn shell,则有“设置-A数据库名称”,否则有“声明数据库名称

要编写适用于所有shell的脚本,

 set -A databaseName=("db1" "db2" ....) ||declare -a databaseName=("db1" "db2" ....)# now loopfor dbname in "${arr[@]}"doecho "$dbname"  # or whatever
done

它应该适用于所有shell。

这也很容易阅读:

FilePath=("/tmp/path1/"    #FilePath[0]"/tmp/path2/"    #FilePath[1])
#Loopfor Path in "${FilePath[@]}"doecho "$Path"done

每个Bash脚本/会话的第一行:

say() { for line in "${@}" ; do printf "%s\n" "${line}" ; done ; }

使用例如:

$ aa=( 7 -4 -e ) ; say "${aa[@]}"7-4-e

可以考虑:echo-e解释为这里的选项

listOfNames="db_one db_two db_three"for databaseName in $listOfNamesdoecho $databaseNamedone

或者只是

for databaseName in db_one db_two db_threedoecho $databaseNamedone

这类似于user2533809的回答,但每个文件将作为单独的命令执行。

#!/bin/bashnames="RARBR CRD"
while read -r line; doecho line: "$line"done <<< "$names"

我循环遍历我的项目数组以进行git pull更新:

#!/bin/shprojects="webiosandroid"for project in $projects docd  $HOME/develop/$project && git pullend

单线循环,

 declare -a listOfNames=('db_a' 'db_b' 'db_c')for databaseName in ${listOfNames[@]}; do echo $databaseName; done;

你会得到这样的输出,

db_adb_bdb_c

for Item in Item1 Item2 Item3 Item4 ;doecho $Itemdone

输出:

Item1Item2Item3Item4

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

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

输出:

Item 1Item 2Item 3Item 4

使列表在多行

for Item in Item1 \Item2 \Item3 \Item4doecho $Itemdone

输出:

Item1Item2Item3Item4

简单列表变量
List=( Item1 Item2 Item3 )

List=(Item1Item2Item3)

显示列表变量:

echo ${List[*]}

输出:

Item1 Item2 Item3

遍历列表:

for Item in ${List[*]}doecho $Itemdone

输出:

Item1Item2Item3

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

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

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

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

输出:

element 1element 2element 3

创建关联数组。字典:

declare -A continent
continent[Vietnam]=Asiacontinent[France]=Europecontinent[Argentina]=America
for item in "${!continent[@]}";doprintf "$item is in ${continent[$item]} \n"done

输出:

 Argentina is in AmericaVietnam is in AsiaFrance is in Europe

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

List="Item 1,Item 2,Item 3"Backup_of_internal_field_separator=$IFSIFS=,for item in $List;doecho $itemdoneIFS=$Backup_of_internal_field_separator

输出:

Item 1Item 2Item 3

如果需要编号:

`

这被称为反向刻度。将命令放在反向刻度内。

`command`

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

List=()Start_count=0Step_count=0.1Stop_count=1for Item in `seq $Start_count $Step_count $Stop_count`doList+=(Item_$Item)donefor Item in ${List[*]}doecho $Itemdone

输出为:

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

更熟悉bashes行为:

在文件中创建列表

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

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

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

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

脚本或函数的隐式数组:

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

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

中有一个特别案例:

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

这可以填充(用于测试)

set -- arg1 arg2 arg3 ...

循环 over这个数组可以简单地编写:

for item ;doecho "This is item: $item."done

说明保留的工作in不存在,也没有数组名称!

样本:

set -- arg1 arg2 arg3 ...for item ;doecho "This is item: $item."doneThis is item: arg1.This is item: arg2.This is item: arg3.This is item: ....

请注意,这与

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

然后进入脚本

#!/bin/bash
for item ;doprintf "Doing something with '%s'.\n" "$item"done

将其保存在脚本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 '...'.

函数中:

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

然后

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

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

arr=(foo bar baz)
for i in ${!arr[@]}doecho $i "${arr[i]}"done

输出:

0 foo1 bar2 baz

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

(0和1不需要引用,因为它们只是数字;有些人会建议引用它们,但这只是个人偏好。

简单方法:

arr=("sharlock"  "bomkesh"  "feluda" )  ##declare array
len=${#arr[*]}  # it returns the array length
#iterate with while loopi=0while [ $i -lt $len ]doecho ${arr[$i]}i=$((i+1))done

#iterate with for loopfor i in $arrdoecho $idone
#iterate with spliceecho ${arr[@]:0:3}

我真正需要的是这样的东西:

for i in $(the_array); do something; done

例如:

for i in $(ps -aux | grep vlc  | awk '{ print $2 }'); do kill -9 $i; done

(将杀死所有名称中带有vlc的进程)

如何循环遍历数组取决于新行字符的存在。使用新行字符分隔数组元素,数组可以称为"$array",否则应称为"${array[@]}"。以下脚本将明确说明:

#!/bin/bash
mkdir tempmkdir temp/aaamkdir temp/bbbmkdir temp/cccarray=$(ls temp)array1=(aaa bbb ccc)array2=$(echo -e "aaa\nbbb\nccc")
echo '$array'echo "$array"echofor dirname in "$array"; doecho "$dirname"doneechofor dirname in "${array[@]}"; doecho "$dirname"doneechoecho '$array1'echo "$array1"echofor dirname in "$array1"; doecho "$dirname"doneechofor dirname in "${array1[@]}"; doecho "$dirname"doneechoecho '$array2'echo "$array2"echofor dirname in "$array2"; doecho "$dirname"doneechofor dirname in "${array2[@]}"; doecho "$dirname"donermdir temp/aaarmdir temp/bbbrmdir temp/cccrmdir temp

我在GitHub更新中使用了这种方法,我发现它很简单。

## declare an array variablearr_variable=("kofi" "kwame" "Ama")
## now loop through the above arrayfor i in "${arr_variable[@]}"doecho "$i"

done   

您可以使用带有三个表达式(C风格)的计数器遍历bash数组值,以读取循环语法的所有值和索引:

declare -a kofi=("kofi" "kwame" "Ama") 
# get the length of the arraylength=${#kofi[@]}
for (( j=0; j<${length}; j++ ));doprint (f "Current index %d with value %s\n" $j "${kofi[$j]}")done