在Bash中循环遍历一串字符串?

时间:2012-01-16 13:21:16

标签: arrays bash shell

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

类似的东西:

for databaseName in listOfNames
then
  # Do something
end

20 个答案:

答案 0 :(得分:1983)

你可以像这样使用它:

## 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

也适用于多行数组声明

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

答案 1 :(得分:661)

当然,这是可能的。

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

有关详细信息,请参阅Bash Loops for, while and until

答案 2 :(得分:168)

这些答案都不包括反击......

#!/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

输出:

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

答案 3 :(得分:100)

与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中。名字中没有空格:

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

备注

  1. 在第二个示例中,使用listOfNames="RA RB R C RD"具有相同的输出。
  2. 引入数据的其他方式包括:

    从标准输入读取

    # 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. bash IFS“字段分隔符到行”[1]分隔符以允许其他空格(即IFS='\n'或MacOS IFS='\r'
    2. 我也喜欢接受的答案:) - 我已经将这些片段作为其他有用的方式包含在内,也可以回答这个问题。
    3. 在脚本文件的顶部包含#!/bin/bash表示执行环境。
    4. 我花了几个月的时间才弄清楚如何对此进行编码:)
    5. 其他来源 (while read loop

答案 4 :(得分:83)

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

输出:

Item1
Item2
Item3
Item4

多行

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

输出:

Item1
Item2
Item3
Item4


简单列表变量

List=( Item1 Item2 Item3 )

List=(
      Item1 
      Item2 
      Item3
     )

显示列表变量:

echo ${List[*]}

输出:

Item1 Item2 Item3

循环浏览列表:

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

输出:

Item1
Item2
Item3

创建一个功能来浏览列表:

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

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

List=(' Item 1 '
      ' Item 2' 
      ' Item 3'
     )
for item in "${List[@]}"; 
  do 
    echo "$item"
  done 

输出:

 Item 1
 Item 2
 Item 3

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

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

输出:

element 1
element 2
element 3

创建关联数组。字典:

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

输出:

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

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

输出:

Item 1
Item 2
Item 3

如果需要编号:

` 

这被称为后退。将命令放在后面。

`commend` 

它位于键盘上的第一位和标签键上方。在标准的美国英语键盘上。

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

输出是:

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

熟悉bashes行为:

在文件中创建列表

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

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

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.

答案 5 :(得分:37)

您可以使用${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

答案 6 :(得分:18)

这也很容易阅读:

int(SUM)

答案 7 :(得分:15)

令人惊讶的是,到目前为止还没有人发表过文章-如果在遍历数组时需要元素的索引,则可以执行以下操作:

arr=(foo bar baz)

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

输出:

0 foo
1 bar
2 baz

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

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

答案 8 :(得分:6)

脚本或函数的隐式数组:

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

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

中有特殊案例:

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

可以通过

填充(测试)
set -- arg1 arg2 arg3 ...

数组上的 循环 可以简单地编写:

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

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

样品:

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: ....

请注意,这与

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

然后进入脚本

#!/bin/bash

for item ;do
    printf "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 time3
Working about 'item1'.
Working about 'tiem2'.
Working about 'time3'.

答案 9 :(得分:4)

listOfNames="db_one db_two db_three"
for databaseName in $listOfNames
do
  echo $databaseName
done

或只是

for databaseName in db_one db_two db_three
do
  echo $databaseName
done

答案 10 :(得分:4)

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

promote_sla_chk_lst="cdi xlob"

set -A promote_arry $promote_sla_chk_lst

for i in ${promote_arry[*]};
    do
            echo $i
    done

答案 11 :(得分:3)

简单方法:

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}

答案 12 :(得分:2)

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

headlamp['word']

答案 13 :(得分:2)

如果您使用的是Korn shell,则有&#34; 设置-A数据库名称&#34;,否则有&#34; 声明-a databaseName &#34;

编写一个处理所有shell的脚本,

 set -A databaseName=("db1" "db2" ....) ||
        declare -a databaseName=("db1" "db2" ....)
# now loop 
for dbname in "${arr[@]}"
do
   echo "$dbname"  # or whatever

done

它应该适用于所有炮弹。

答案 14 :(得分:1)

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

int x = 20;
int n = 12;
ArrayList<Integer> list = new ArrayList<>();
int f = x / n;
int r = x % n;
for(i = 0; i < n; i++) {
    if(i <= n - r) list.add(f);
    else list.add(f + 1)
}

使用例如:

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

可以考虑:$ aa=( 7 -4 -e ) ; say "${aa[@]}" 7 -4 -e echo解释为此处的选项

答案 15 :(得分:1)

单行循环,

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

你会得到这样的输出,

db_a
db_b
db_c

答案 16 :(得分:1)

试试这个。它正在运行和测试。

for k in "${array[@]}"
do
    echo $k
done

# For accessing with the echo command: echo ${array[0]}, ${array[1]}

答案 17 :(得分:0)

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

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

例如:

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

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

答案 18 :(得分:0)

如何遍历数组取决于是否存在换行符。用换行符分隔数组元素,数组可称为"$array",否则应称为"${array[@]}"。以下脚本将清楚说明:

#!/bin/bash

mkdir temp
mkdir temp/aaa
mkdir temp/bbb
mkdir temp/ccc
array=$(ls temp)
array1=(aaa bbb ccc)
array2=$(echo -e "aaa\nbbb\nccc")

echo '$array'
echo "$array"
echo
for dirname in "$array"; do
    echo "$dirname"
done
echo
for dirname in "${array[@]}"; do
    echo "$dirname"
done
echo
echo '$array1'
echo "$array1"
echo
for dirname in "$array1"; do
    echo "$dirname"
done
echo
for dirname in "${array1[@]}"; do
    echo "$dirname"
done
echo
echo '$array2'
echo "$array2"
echo
for dirname in "$array2"; do
    echo "$dirname"
done
echo
for dirname in "${array2[@]}"; do
    echo "$dirname"
done
rmdir temp/aaa
rmdir temp/bbb
rmdir temp/ccc
rmdir temp

答案 19 :(得分:-4)

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

#!/bin/sh
projects="
web
ios
android
"
for project in $projects do
    cd  $HOME/develop/$project && git pull
end