パス名拡張を使用して変数にファイル名を割り当てる

パス名拡張を使用して変数にファイル名を割り当てる

パス名拡張を利用してファイル名を変数に割り当てる安定した方法はありますか?

これはうまくいきますが、少し奇妙に見えます。

the_file="$(echo ~/downloads/stack-*-linux-x86_64-static.tar.gz)"

ファイルが存在するとフルパスが割り当てられ$the_file、そうでなければ偽のglobパターンが発生します。

答え1

ワイルドカードはリストコンテキストでのみ発生するため、次に割り当てる必要があります。大量に変える、、、またはksh93bashzshmkshyash

the_files=(~/downloads/stack-*-linux-x86_64-static.tar.gz)

またはsh:

set -- ~/downloads/stack-*-linux-x86_64-static.tar.gz

割り当て$1$2...

そして最初の要素を取得します:"${the_files[1]}"in zshor yash(または$the_files[1]in zsh) または"${the_files[0]}"in kshor bash.

すべての要素について:("${the_files[@]}"にも$the_filesありますzsh)。

$IFS:("${the_files[*]}"また)"$the_files"の最初の文字で連結された要素を結合するために使用されますzsh。またはzsh:の文字列に関連付けられています${(j:, :)the_files}(ここでは、に関連付けられています,)。

注意することがあります

スカラー変数に代入

the_file=~/downloads/stack-*-linux-x86_64-static.tar.gz

~拡大するけどいいえ世界的な。ただし、次のように変数を展開するときに引用符を使用することを忘れた場合:

printf '%s\n' $the_file # instead of printf '%s\n' "$the_file"

その後、$the_fileコンテンツを分割してグローバルに展開します。その瞬間これはうまくいくと思うかもしれませんが、実際にはそうではなく、チルダ拡張と組み合わせるとはるかに混乱する可能性があります。

たとえば、$HOMEis/All * Users/me$IFSisがデフォルトに設定されている場合は、現在のディレクトリのすべてのファイル名(拡張子)が$the_file含まれて印刷され、/All * Users/me/downloads/stack-*-linux-x86_64-static.tar.gzその後に続きます。printf/All*Users/me/downloads/stack-*-linux-x86_64-static.tar.gz

パターンがどのファイルとも一致しない場合の対処

ではzshエラーが発生しますが、他のシェルではパターンは同じままです。最良のシナリオは、パターンがまったく拡張されないことです。

zshつまり、Nglob修飾子を使用します。

the_files=(~/downloads/stack-*-linux-x86_64-static.tar.gz(N))

ksh93glob演算子に~(N)似た機能があります:

the_files=(~/downloads/~(N)stack-*-linux-x86_64-static.tar.gz)

shopt -s nullglob他のシェルでは、一部のグローバルオプション(in bashset -o nullglobin)を有効にする必要がありますyash

関連情報