web-dev-qa-db-ja.com

Bash-globを使用して反転ファイルリストを出力します

Globを介してファイルリストを逆にする方法はありますか?

したがって、次の場合と同じ結果が得られます。

ls -r *

私はこれをシェルスクリプトで使用していますが、shellcheckは文句を言い続けます:

^ -------- ^ SC2045:ls出力の反復は壊れやすいです。グロブを使用します。

1
nath

この質問は、ファイル名のグロブパターンから生じるリストを逆にすることに関するものであり、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オプションを追加で設定します。

3
Kusalananda

どのシェルを使用しているのかはわかりません。英数字の昇順以外でグロブするシェルに出くわしたことはありません。つまり、これはlssort、またはそのようなもので行う必要があることです。 lsの出力を反復処理することが壊れやすい理由とその対処方法については、 shellcheck wiki を参照してください。基本的に、注意すべき2つの主な問題があります。1)ディレクトリが空の場合、echo *プリント*デフォルトで。 2)名前にスペースが含まれるファイルがある場合、入力を読み取るものが混乱する可能性があります。 (1)の場合、bashを使用している場合は、nullglobオプションを設定する必要があります。 (2)の場合、おそらく次の行に沿って何かを書きたいと思うでしょう。

ls -1r | while read filename; do
    ...
done

(ここでも、shbash、またはzshを使用していると仮定します。)

0
arensb

Globを介してファイルリストを逆にする方法はありますか?

いいえ、globから逆ファイルリストを取得する直接的な方法はありません。

ただし、いくつかのシェルの要素の配列を逆にするためのさまざまな解決策があります。

POSIXシェルの最も基本的なソリューションは次のとおりです。

  • ファイルのリストを位置引数に設定します。

    セットする - *

  • 位置引数の配列を逆にします。

    フラグ= ''; 「$ @」の場合; set-"$ a" $ {flag-"$ @"};未設定のフラグ。完了

バリエーションのある同じプロセスを他のシェルに適用できます。

bash

配列を持つシェルの場合(質問にタグを付けたもののように: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に特化した回答がすでにあります。

0
Isaac