globでファイルリストを元に戻す方法はありますか?
したがって、次のような結果が得られます。
ls -r *
シェルスクリプトでこれを使用していますが、文句を言い続けますshellcheck
。
^---------^ SC2045: 繰り返し ls 出力が脆弱です。グローバルを使用してください。
答え1
扱いにくい
シェルを使用すると、(順序)、(逆と同じ)、および(数値の場合)glob修飾子を使用してzsh
globのソート順序をカスタマイズできます。oC
OC
^oC
n
引用するinfo zsh qualifier
:
oC
ファイル名のソート方法を指定します。 Cの場合は名前でソートされ、
n
ファイルL
のサイズ(長さ)でソートさl
れます。変更またはinodeの変更がある場合、サブディレクトリのファイルは、すべての検索レベルで現在のディレクトリのファイルの前に表示されます。これは、同じディレクトリ内のファイル名をソートするために ""などの他の条件と組み合わせて使用するのが最善です。ソートが実行されます。 、、、ageは現在時刻と比較されるため、リストの最初の名前は最も若いファイルです。また、修飾子とが使用されるため、 ''はシンボリックリンクの直後にファイルサイズの降順ですべてのファイルのリストを提供します。使用しない限り、複数の順序指定子が関係を解決しているように見えることがあります。a
m
c
d
odon
N
a
m
c
^
-
*(^-oL)
oN
glob修飾子を使用しない限り、デフォルトのソートは
n
(名前に基づいて)であり、この場合は(ソートされていません)です。Y
N
oe
そしてo+
特別なケースです。それぞれの後には、e
glob修飾子とglob修飾子で+
区切られたシェルコードが続きます(上記を参照)。コードは一致する各ファイルに対して実行され、パラメータはREPLY
エントリのファイル名に設定され、コードは任意の方法でパラメータを変更する必要がありますglobsort
。戻り値は、ファイル名の代わりに引数値をソートする文字列として使用します。他のソート演算子とは異なり、およびは繰り返すことができますが、すべてのglob式に表示できるすべてのタイプのソート演算子の最大数は12です。zsh_eval_context
REPLY
oe
o+
したがって、アルファベットの逆順でファイルのリストを取得するには、次のようにします。
list=(*(NOn))
または
list=(*(N^on))
N
((for)修飾子はここでも使用されるため、nullglob
一致するファイルがない場合はリストが空になります。)
変更時間に基づいて逆順にソートされたリストの場合(例ls -rt
:):
list=(*(NOm))
o
O
zshを使用すると、パラメータ拡張フラグを使用して配列要素を並べ替えることもできます。
list=(*(N))
list_reversed=(${(Oa)list})
つまり、配列メンバーを$list
逆順に並べ替えます(大文字の使用のためO
)a
。
強く打つ
最新バージョンのbash
シェルとGNUを使用すると、sort
逆順に並べられたファイル名のリストを取得できます。
readarray -td '' list < <(
shopt -s nullglob
set -- *
(($# == 0)) || printf '%s\0' "$@" | sort -rz)
readarray -td '' array
NULで区切られたレコードのリストを配列に読み込みます。
GNU実装の場合、ls
別のアプローチは次のとおりです。
eval "list=($(ls --quoting-style=shell-always -r))"
ここではls --quoting-style=shell-always
、一重引用符を使用してファイル名を引用します(\'
一重引用符の外に一重引用符自体を引用します)。
このアプローチも機能しますyash
(すべてのファイル名がロケールで有効なテキストであると仮定します)。ただしksh93
、この場合は変数を事前に配列として宣言する必要があります(使用)。それ以外の場合、出力が提供されない場合は複合として生成されます。代わりに、変数は配列変数ではありません。zsh
mksh
ksh93
typeset -a list
ls
$list
ls
ast-open実装もオプションをサポートしていますが、引用形式を--quoting-style=shell-always
使用しているため、すべてのロケールで使用するのは安全ではありません。$'...'
POSIXとして
POSIXly、配列をsh
反転するには、次のことができます。"$@"
eval "set -- $(awk 'BEGIN {for (i = ARGV[1]; i; i--) printf " \"${"i"}\""}' "$#")"
アイデアは、3つの要素があるset -- "${3}" "${2}" "${1}"
ときに出力と同じawk出力を持つことです。"$@"
したがって、ファイルのリストを逆順に取得するには、次の手順を実行します。
set -- *
eval "set -- $(awk 'BEGIN {for (i = ARGV[1]; i; i--) printf " \"${"i"}\""}' "$#")"
echo file list:
printf ' - %s\n' "$@"
POSIXには、同等のオプション(発明)、zshのglob修飾子、またはksh93のglob演算子はsh
ありません。現在のディレクトリに隠されていないファイルがない場合は、1つの要素しかないリストが生成されます。この問題を解決する一般的な方法は次のとおりです。nullglob
zsh
(N)
~(N)
*
set -- [*] *
case "$1$2" in
('[*]*') shift 2;;
(*) shift;;
esac
ここで、[*]
「and」の組み合わせは*
「a」と区別される*
方法です。矛盾([*]
にも拡張[*]
)とリテラル名のファイル*
([*]
にも拡張*
)です。
とにかく、シェルが拡張を渡す方法ls
など、ソートするファイル名のリストを渡す場合は、オプションを使用して次のようにオプションの終わりを表示する必要があります。ls -r *
*
-d
--
ls -rd -- *
ただし、ファイル名は改行で区切られ、改行はファイル名のすべての文字と同じくらい有効であるため、この出力はまだ安定して後処理できません。
答え2
この質問は、ファイル名globbingパターンを再実装するのではなく、生成されたリストを反転することについて考えていますls -r
。
位置パラメータのグローバル一致結果を取得します。たとえば、次のようになります。
set -- *
その後、リストを逆に置き換えます。
names=()
for name do
shift
names[$#]=$name
done
names
これにより、反転されたワイルドカードパターンの一致を含む名前の配列が作成されます*
。
位置引数(一致結果)を順番に繰り返し、各項目の反転リストの位置に挿入して反転を実行します。$#
は位置引数(ワイルドカードパターンと一致)の数であり、そのリストから1つを削除し、各shift
反復$#
ごとに1ずつ減らすため、位置引数リストの先頭から配列の最後まで要素を挿入しますnames
。
names
配列があれば印刷します。
printf '%s\n' "${names[@]}"
...または必要なものをすべて実行してください。
これはいいえls -r *
このコマンドと同様に、ls
globと一致するすべてのディレクトリの内容が一覧表示されます*
。
一致するものがない場合は、bash
パターンを展開しないでください。アクティブ化時に名前と一致しないパターンを完全に削除するshopt -s nullglob
シェルを設定するオプション。nullglob
隠された名前を一致させるには、追加のシェルdotglob
オプションを設定します。
答え3
どのシェルを使用しているのか言っておらず、英数字の昇順以外の操作を実行するシェルを見たことはありません。したがって、これを行うにはls
、sort
または同様のものを使用する必要があります。バラよりシェルチェックウィキ繰り返しの出力がls
脆弱な理由とそれを解決する方法基本的に注目すべき2つの主な問題があります。 1)ディレクトリが空のときにデフォルトでecho *
印刷されます。*
2) ファイル名にスペースが含まれている場合、入力内容の読み込みに混乱を招く可能性があります。 (1)の場合、bashを使用している場合はこのオプションを設定する必要がありますnullglob
。 (2)の場合は、次の内容を作成したい場合があります。
ls -1r | while read filename; do
...
done
sh
(もう一度言うが、bash
またはを使用すると仮定しますzsh
。)
答え4
ほとんどのシェルに移植可能であり、1つのファイルでエラーを防ぎます(seq
与えられたシェルのみを使用しprintf
てset
)eval
。
set -- *
[ $# -gt 1 ] && eval set -- "$(printf "\"\${%s}\" " $(seq "$#" -1 1))"
printf '%s ' "$@"
可能であれば、nullglob と failedglob を設定するのが妥当です。