Globを介してファイルリストを逆にする方法はありますか?
したがって、次の場合と同じ結果が得られます。
ls -r *
私はこれをシェルスクリプトで使用していますが、shellcheck
は文句を言い続けます:
^ -------- ^ SC2045:ls出力の反復は壊れやすいです。グロブを使用します。
この質問は、ファイル名のグロブパターンから生じるリストを逆にすることに関するものであり、ls -r
の正確な出力を再実装することに関するものではないと想定します。
グロブマッチの結果を例えばに取得します。位置パラメータ:
set -- *
次に、そのリストを逆にします。
names=()
for name do
shift
names[$#]=$name
done
これにより、*
グロブパターンの一致が逆になっているnames
という配列が作成されます。
反転は、位置パラメーター(一致の結果)を順番に繰り返し、各エントリについて、反転リストの位置に挿入することによって行われます。 $#
は位置パラメータ(グロブパターンの一致)の数であり、shift
はこのリストから1つを削除し、反復ごとに$#
を1つずつ減らします。そのため、次の要素を挿入します。位置パラメータのリストの先頭からnames
配列の末尾まで。
names
配列を取得したら、それを出力します。
printf '%s\n' "${names[@]}"
...またはそれを使って必要なことは何でもします。
これはnotls -r *
と同じになります。これは、ls
コマンドが*
グロブと一致するディレクトリの内容を一覧表示するためです。
パターンが何にも一致しない場合、bash
はパターンを展開しないままにします。 shopt -s nullglob
を使用して、シェルのnullglob
オプションを設定します。これをアクティブにすると、どの名前とも一致しない場合にパターンが完全に削除されます。非表示の名前と一致させるには、シェルのdotglob
オプションを追加で設定します。
どのシェルを使用しているのかはわかりません。英数字の昇順以外でグロブするシェルに出くわしたことはありません。つまり、これはls
、sort
、またはそのようなもので行う必要があることです。 ls
の出力を反復処理することが壊れやすい理由とその対処方法については、 shellcheck wiki を参照してください。基本的に、注意すべき2つの主な問題があります。1)ディレクトリが空の場合、echo *
プリント*
デフォルトで。 2)名前にスペースが含まれるファイルがある場合、入力を読み取るものが混乱する可能性があります。 (1)の場合、bashを使用している場合は、nullglob
オプションを設定する必要があります。 (2)の場合、おそらく次の行に沿って何かを書きたいと思うでしょう。
ls -1r | while read filename; do
...
done
(ここでも、sh
、bash
、またはzsh
を使用していると仮定します。)
Globを介してファイルリストを逆にする方法はありますか?
いいえ、globから逆ファイルリストを取得する直接的な方法はありません。
ただし、いくつかのシェルの要素の配列を逆にするためのさまざまな解決策があります。
POSIXシェルの最も基本的なソリューションは次のとおりです。
ファイルのリストを位置引数に設定します。
セットする - *
位置引数の配列を逆にします。
フラグ= ''; 「$ @」の場合; set-"$ a" $ {flag-"$ @"};未設定のフラグ。完了
バリエーションのある同じプロセスを他のシェルに適用できます。
配列を持つシェルの場合(質問にタグを付けたもののように:bash(またはksh、zsh、またはその他)):
files=( * )
min=0
max=$(( ${#files[@]} -1 ))
while [[ min -lt max ]]
do
# Swap current first and last elements
x="${files[$min]}"
files[$min]="${files[$max]}"
files[$max]="$x"
# Move closer
(( min++, max-- ))
done
printf '%s\n' "${files[@]}"
min
およびmax
インデックスを使用すると、プロセスが高速になります。
zsh
に特化した回答がすでにあります。