1. ホーム
  2. スクリプト・コラム
  3. リナックスシェル

シェルで配列をトラバースするいくつかの方法

2022-02-08 06:18:31

背景

ある日、次のような現象に遭遇しました。最初の探索では普通に要素が表示されるのに、2番目の探索では1つの要素しか表示されないのです!

#! /bin/bash
# $1 for the file directory
# Execute eg.
# sh your_shell.sh /user/lib/
 
echo "Start time: `date '+%Y-%m-%d %H:%M:%S'`"
# 1. Get all files
files=`ls $1`
 
# 2, define 1 array variable
declare -a array_files01
 
 
# array index initialized to 0
m1=0
 
 
# traverse
for ays in ${files}; do
{
 # Get the length of the array
 num_1=${#array_files01[@]}
 
 # Add elements to the array, index takes +1 each time
 array_files01[m1]=${ays};
 m1=`expr ${m1} + 1`;
 
 fi
}
done
 
echo "End of allocation array time: `date '+%Y-%m-%d %H:%M:%S'`"
# Print prompt message
echo "1 array length: ${#array_files01[@]}"
 
# The first traversal: normal
for i in ${array_files01[@]}; do
 echo $i
done 
 
# Second traversal: abnormal
for i in ${array_files01}; do
 echo $i
done 


配列をトラバースするいくつかの方法

1. フォーループ

################### The first #######################
for i in ${array[@]}
# can also be written for element in ${array[*]}
do
echo $i
done

################## The second ########################
for i in ${array[*]}
do
echo $i ;
done
 
################## third ########################
for(( i=0;i<${#array[@]};i++)) do
#${#array[@]} gets the length of the array for looping
echo ${array[i]};
done;

2. while ループ

i=0 
while [ $i -lt ${#array[@]} ] 
# Enter the loop body when the variable (subscript) is less than the length of the array
do 
 echo ${ array[$i] } 
 #Print the elements of the array by subscript
 let i++ 
done 


下付き文字の問題に加えて、@と*は正確に等価ではなく、二重引用符で囲まれた場合、若干異なるパースをすることがあることに注意が必要です。

  • は * と互換性があり、ダブルクォートで囲まれた場合は "${#arr1[@]}"と等価です。
  • の場合。.in traversalで、配列要素を直接トラバースする場合、${arr1[@]}をダブルクォートで囲まない場合、@は*と同等ですが、配列要素をパースすると、要素の内容もスペースで区切ることになり、パースエラーになります。また、${arr1[*]}をダブルクォーテーションで囲むと、配列のすべての要素が空白で区切られ、1つの要素として扱われ、これもまた正しくパースされません。arr1[@]} をダブルクォートで囲んだ場合のみ、配列の要素を正しくパースすることができますので、配列の要素を直接たどる場合は、 ""${arr1[@]}"" というメソッドを使用する必要があります。配列の要素を添え字で走査する場合、${!arr1[*]}をダブルクォートで囲むと、要素の添え字がすべてカンマ区切りで文字列になるので、この方法では添え字セットを取得できず、他の3つのケースでは添え字を正しく取得することができる。
  • トラバーサル中に、@、*、ダブルクォートの影響を受けません。

シェルによる配列の反復処理については、この記事がすべてです。シェルによる配列の反復処理については、過去の記事を検索するか、以下の記事を引き続き閲覧してください。