ฉันต้องการเขียนสคริปต์ที่วนรอบ 15 สาย (อาจเป็นไปได้หรือไม่) เป็นไปได้ไหม
สิ่งที่ต้องการ:
for databaseName in listOfNames
then
# Do something
end
ฉันต้องการเขียนสคริปต์ที่วนรอบ 15 สาย (อาจเป็นไปได้หรือไม่) เป็นไปได้ไหม
สิ่งที่ต้องการ:
for databaseName in listOfNames
then
# Do something
end
คำตอบ:
คุณสามารถใช้สิ่งนี้:
## 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"
)
แน่นอนว่าเป็นไปได้
for databaseName in a b c d e f; do
# do something like: echo $databaseName
done
ดูBash Loops ในขณะและจนกว่าจะมีรายละเอียด
for year in $(seq 2000 2013)
นี้ทำงานได้ดีกับแทนคำสั่งเช่น
DATABASES="a b c d e f"
มันทำความสะอาดและคุณสามารถนำมาใช้อาร์เรย์เพียงโดยการตั้งค่าสตริงคือ
คำตอบเหล่านั้นไม่มีตัวนับรวม ...
#!/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
echo "$i / ${arraylength} : ${array[$i-1]}"
- มิฉะนั้นหากคุณ$i
มีรูปกลมมันจะถูกขยายถ้ามีแท็บก็จะเปลี่ยนเป็น ช่องว่าง ฯลฯ
ใช่
for Item in Item1 Item2 Item3 Item4 ;
do
echo $Item
done
เอาท์พุท:
Item1
Item2
Item3
Item4
เพื่อรักษาช่องว่าง รายการคำพูดเดี่ยวหรือสองรายการและการขยายรายการคำพูดสองครั้ง
for Item in 'Item 1' 'Item 2' 'Item 3' 'Item 4' ;
do
echo "$Item"
done
เอาท์พุท:
Item 1
Item 2
Item 3
Item 4
เพื่อสร้างรายชื่อมากกว่าหลายบรรทัด
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[*]}
การใช้คีย์เวิร์ด 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
มีความคุ้นเคยกับพฤติกรรมการขัดข้อง:
สร้างรายการในไฟล์
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: ความหมายพิเศษของอักขระหรือคำบางคำในเชลล์
"${List[@]}"
ถูกต้องด้วยคำพูด ${List[@]}
มันผิด. ${List[*]}
มันผิด. ลองList=( "* first item *" "* second item *" )
- คุณจะได้รับพฤติกรรมที่ถูกต้องfor item in "${List[@]}"; do echo "$item"; done
แต่ไม่ได้มาจากตัวแปรอื่น ๆ
List=( "first item" "second item" )
จะถูกแบ่งออกเป็นfirst
, item
, second
, item
เช่นกัน)
ls
ผลลัพธ์ในทางที่ไม่เหมาะสม
ในจิตวิญญาณเดียวกับคำตอบของ 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
หมายเหตุ
listOfNames="RA RB R C RD"
มีเอาต์พุตเหมือนกันวิธีอื่นในการนำข้อมูลมารวมถึง:
อ่านจาก 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
IFS='\n'
หรือสำหรับ MacOS IFS='\r'
)#!/bin/bash
ที่ด้านบนของไฟล์สคริปต์บ่งชี้ถึงสภาพแวดล้อมการทำงานแหล่งข้อมูลอื่น ๆ ( ขณะอ่านลูป )
IFS
ฉันเพิ่มความคิดเห็นรหัสที่มีการอ้างอิงถึง (สำหรับทุกคนIFS
ให้หนึ่งระบุตัวคั่นที่เฉพาะเจาะจงซึ่งช่วยให้ช่องว่างอื่น ๆ ที่จะรวมอยู่ในสตริงโดยไม่ต้องแยกออกเป็นสารตั้งต้น)
$databaseName
เพียงแค่มีรายการทั้งหมดจึงทำซ้ำเพียงครั้งเดียว
คุณสามารถใช้ไวยากรณ์ของ ${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
แปลกใจที่ไม่มีใครโพสต์สิ่งนี้ - ถ้าคุณต้องการดัชนีขององค์ประกอบในขณะที่คุณวนลูปผ่านอาร์เรย์คุณสามารถทำได้:
arr=(foo bar baz)
for i in ${!arr[@]}
do
echo $i "${arr[i]}"
done
เอาท์พุท:
0 foo
1 bar
2 baz
ฉันพบว่ามันดูหรูหรากว่าสไตล์ for-loop แบบดั้งเดิม ( for (( i=0; i<${#arr[@]}; i++ ))
)
( ${!arr[@]}
และ$i
ไม่จำเป็นต้องเสนอราคาเพราะเป็นเพียงตัวเลขบางคนอาจแนะนำให้อ้างถึงพวกเขาต่อไป แต่นั่นเป็นเพียงการตั้งค่าส่วนตัว)
นี่ยังอ่านง่าย:
FilePath=(
"/tmp/path1/" #FilePath[0]
"/tmp/path2/" #FilePath[1]
)
#Loop
for Path in "${FilePath[@]}"
do
echo "$Path"
done
IFS=$'\n'
สิ่งนี้อาจใช้ได้กับโซลูชันอื่นในสถานการณ์นี้เช่นกัน
นอกจากคำตอบที่ถูกต้องของ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.sh
, chmod +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'.
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
วิธีง่าย ๆ :
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}
อาร์เรย์ที่ประกาศไม่ทำงานสำหรับ Korn เชลล์ ใช้ตัวอย่างด้านล่างสำหรับ Korn เชลล์:
promote_sla_chk_lst="cdi xlob"
set -A promote_arry $promote_sla_chk_lst
for i in ${promote_arry[*]};
do
echo $i
done
for i in ${foo[*]}
โดยทั่วไปมักเป็นสิ่งที่ผิด - for i in "${foo[@]}"
เป็นรูปแบบที่รักษาขอบเขตของรายการดั้งเดิมและป้องกันการขยายตัวของ glob และเสียงสะท้อนต้องเป็นecho "$i"
คล้ายกับคำตอบของผู้ใช้ 2533809 แต่แต่ละไฟล์จะถูกดำเนินการเป็นคำสั่งแยกต่างหาก
#!/bin/bash
names="RA
RB
R C
RD"
while read -r line; do
echo line: "$line"
done <<< "$names"
หากคุณกำลังใช้ Korn เชลล์จะมี " set -A databaseName " มิฉะนั้นจะมี " ประกาศ -a databaseName "
ในการเขียนสคริปต์ที่ทำงานกับเชลล์ทั้งหมด
set -A databaseName=("db1" "db2" ....) ||
declare -a databaseName=("db1" "db2" ....)
# now loop
for dbname in "${arr[@]}"
do
echo "$dbname" # or whatever
done
มันควรจะใช้ได้กับกระสุนทุกตัว
$ bash --version
GNU bash, รุ่น 4.3.33 (0) - ปล่อย (amd64-portbld-freebsd10.0) $ set -A databaseName=("db1" "db2" ....) || declare -a databaseName=("db1" "db2" ....)
bash: ข้อผิดพลาดทางไวยากรณ์ใกล้โทเค็นที่ไม่คาดคิด `('
ลองสิ่งนี้ มันทำงานและทดสอบ
for k in "${array[@]}"
do
echo $k
done
# For accessing with the echo command: echo ${array[0]}, ${array[1]}
array=( "hello world" )
หรือarrray=( "*" )
; ในกรณีแรกมันจะพิมพ์hello
และworld
แยกในครั้งที่สองมันจะพิมพ์รายชื่อไฟล์แทน*
บรรทัดแรกที่เป็นไปได้ของสคริปต์ / เซสชัน Bash ทุกอัน:
say() { for line in "${@}" ; do printf "%s\n" "${line}" ; done ; }
ใช้เช่น:
$ aa=( 7 -4 -e ) ; say "${aa[@]}"
7
-4
-e
อาจพิจารณา: echo
ตีความ-e
ว่าเป็นตัวเลือกที่นี่
การวนซ้ำบรรทัดเดียว
declare -a listOfNames=('db_a' 'db_b' 'db_c')
for databaseName in ${listOfNames[@]}; do echo $databaseName; done;
คุณจะได้ผลลัพธ์เช่นนี้
db_a
db_b
db_c
สิ่งที่ฉันต้องการจริงๆสำหรับสิ่งนี้คือสิ่งนี้:
for i in $(the_array); do something; done
ตัวอย่างเช่น
for i in $(ps -aux | grep vlc | awk '{ print $2 }'); do kill -9 $i; done
(จะฆ่ากระบวนการทั้งหมดด้วย vlc ในชื่อของพวกเขา)
ฉันวนรอบโครงการของฉันสำหรับการgit pull
อัปเดต:
#!/bin/sh
projects="
web
ios
android
"
for project in $projects do
cd $HOME/develop/$project && git pull
end