ファイルのワイルドカードパターンを二重引用符で囲む方法は?

ファイルのワイルドカードパターンを二重引用符で囲む方法は?

このような質問をたくさん見ましたが、同じ質問はありませんでした。

ワイルドカード拡張を使用して単一引用符引数としてコマンドに渡したいファイルディレクトリがあります。

文書

a.ext
b.ext
c.ext

必須使用

command --flag "a.ext b.ext c.ext"

現在使用中ですが、動作command --flag $(echo \"$(echo ./*.ext)\")せず不必要に複雑なようです。これを行う簡単な方法はありますか?

答え1

SPC文字拡張グローブで生成されたファイル名を関連付けるには、それを場所パラメータに保存してそれを使用して"$*"接続できます。

set -- ./*.ext
IFS=' ' # SPC is the first character of $IFS by default, we're setting it
        # here in case that code is called in a context where it has been
        # modified before.
files_joined_with_SPC="$*"
cmd --flag "$files_joined_with_SPC"

または:

cmd --flag "$*"

もちろん、直接(現在の値によって変わるという事実を忘れる方が簡単ですが$IFS)。

上記は標準のPOSIXsh構文です。zsh// ksh93// bash/では、位置引数の代わりに配列を使用することもできますmkshyash

files=(./*.ext)
IFS=' '; files_joined_with_SPC="${files[*]}"

Pass zsh、次を使用することもできます。

files=(./*.ext)
cmd --flag "${(j[ ])files}"

または匿名関数を使用してください。

(){ cmd --flag "${(j[ ])argv}"; } ./*.ext

j次のグローバルパラメータ$IFSに依存せずにSPCの使用を明示的に要求します。

これで、SPCはファイルパスのすべての文字で有効になります。 NULを除くファイルパスのすべての文字が有効です(実際にはすべての文字)。バイト値ほとんどのシステムでゼロの場合、これらのバイトは有効な文字を形成する必要はありませんが、次のコマンドの引数としてNULを渡すことはできません。処刑された

あなたはそれが何であるか言わないcommandはい(ちなみに、これはプレースホルダーとしてcommand使用することを好む標準シェル組み込みの名前です)。ただし、これがファイル名のリスト(SPCで区切られている)を許可したい場合は、次の方法でユーザーが指定できる方法が必要です。ファイル名。cmdcmd --flag listSPC

これはcmd --flag 'with\ space.ext other.ext'、またはなどにすることができますcmd --flag 'with%20space.ext other.extcmd --flag 'with\040space.ext other.ext'

この場合、パラメーターを構成するときに以下をcmd --flag行う必要があります。脱出するSPCに接続する前に、ファイル名に\SPC(および可能な文字)を含めてください。%

ksh93// zsh/ では、bash次のことyashができます。

escaped_files=("${files[@]//\\/\\\\}") # \ escaped as \\
escaped_files=("{files[@]// /\\ }")    # SPC escaped as \SPC
# more characters may need to be escaped such as other whitespace
# or quoting characters, depending on the exact syntax expected by
# cmd for the --flag option.

IFS=' '; escaped_files_joined_with_SPC="$*"
cmd -- flag "$escaped_files_joined_with_SPC"

(GB18030、BIG5などの文字エンコーディングを使用するロケールには、これらの文字の一部にバックスラッシュエンコーディング(バイト0x5c)が含まれていることに注意してください。シェルはこれらの0x5cバイトをエスケープできませんが、デコードされてcmd --flagいないと処理されますロケールの文字セットに応じてバックスラッシュ引数として使用されます。

より信頼性が高く便利なコマンド方法が得られます。リストファイル名は別の引数(したがってオプションの引数ではありません)またはcmd --flag 'file 1.ext' --flag 'file 2.ext'...

答え2

引用符付き文字列ですべてのファイル名を取得するには:

command --flag "$(echo ./*.ext)"

ご存知のように、これは単純なファイル名でのみ機能します。これはファイル名にスペースがないことを意味します。値によってはxpg_echoバックスラッシュがないことを意味する場合もあります(ヒント:先行)。

答え3

glob 拡張ファイルの for ループを設定します。 var というシェル変数をファイル名のコンテナとして使用します。反復ごとにシェル変数varを更新します。

var=
for f in *.ext; do var=${var-}${var:+ }$f; done
your_command --flag "$var"

関連情報