フォルダ内の各ファイルに基づいてインデックスを作成するスクリプトがあります。すべてのファイル名は拡張子を含む数字です。
数値順に処理するようにループを変更するにはどうすればよいですか?
for file in xml/*.xml; do
...
done
答え1
GNU sort
区切り文字を区切るオプションがある場合は、\0
これを実行できます。これにより、while
ループが処理できるようにファイルが並べ替えられた順序でインポートされ始めます。printf
このオプションをカスタムロジックに置き換えます。
shopt -s nullglob
printf '%s\0' xml/*.xml | sort -zV | while read -rd '' file; do
printf "%s\n" "$file"
done
shopt -u nullglob
このオプションは、現在のフォルダにファイルが見つからない場合にnullglob
シェルが空のグローブを拡張するのを防ぐためです。処理が完了すると、xml
このオプションは設定解除されます。-u
〜のようにトニースペートシェルオプションを混乱させたくない場合(たとえば、他の理由でアクティブになる可能性がある場合)、これをサブシェルに設定してグローバル拡張が行われるようにします。
( shopt -s nullglob; printf '%s\0' xml/*.xml ) | sort -zV | while read -rd '' file; do
printf "%s\n" "$file"
done
答え2
zshが利用可能な場合(スクリプトの場合、開発の容易さと展開の容易さが妥協されます):
for file in xml/*.xml(n); do
...
done
これグローバル予選 n
foo10bar
globパターンの一致を並べ替えるとき、数値シーケンスはアルファベット順、つまり次のものではなく、整数の数値順に並べ替える必要があることを指定しますfoo9bar
。
また、使用することができますsetopt numeric_glob_sort
すべてのglobモードにこの設定を有効にします。
答え3
~に沿ってクサロナンダの提案の一つ:
準備する:
mkdir xml && cd xml
touch 1.xml 10.xml 23.xml 999.xml
cd ..
リング:
for f in {1..100}; do [ -f "xml/$f.xml" ] && echo process "xml/$f.xml"; done
結果:
process xml/1.xml
process xml/10.xml
process xml/23.xml
最大のデジタルファイルに対応できるように、支柱拡張ループを大きくします。
答え4
ls -Q xml*.xml | while read line;do
...
done
lsはファイルを番号順にリストし、-Qはすべてのスペースが処理されるようにします。