globを展開し、各ファイル名の前にフラグを挿入します。

globを展開し、各ファイル名の前にフラグを挿入します。

次の構文のパラメータを必要とするプログラムがあります。

prog [-f filename | -g filename1 filename2] ...

すべてのファイル名の前にこのフラグを付ける必要があります-f。たとえば、次は有効な呼び出しですprog

prog -f a.txt -g b.txt c.txt -f d.txt
prog -g a.txt b.txt -g c.txt d.txt
prog -f a.txt -f b.txt -f c.txt

...しかし、次はそうではありません。

prog -f a.txt b.txt
prog -f a.txt -g b.txt
prog a.txt

私に関する限り、私は-f選択についてです。

私のディレクトリには次のファイルがたくさんあります.txt

important-files/
├── a.txt
├── b.txt
├── c.txt
├── d.txt
└── filename with spaces.txt

各ファイルを1つずつリストする必要がないようにしたいと思います。通常、これを行うには単純なglobを使用します。

$ prog important-files/*.txt

ただし、これは次のような誤った呼び出しを生成するため、機能しません。

$ prog important-files/a.txt important-files/b.txt important-files/c.txt important-files/d.txt 'important-files/filename with spaces.txt'

...本当にこの電話を受けたい場合:

$ prog -f important-files/a.txt -f important-files/b.txt -f important-files/c.txt -f important-files/d.txt -f 'important-files/filename with spaces.txt'

...各ファイル名-fprog-g

globを使用して拡張ファイルにフラグを追加する最も短い方法は何ですか?

答え1

Null で区切られた入力を使用してprintfサポートxargsします。

printf -- '-f\0%s\0' important-files/*.txt | xargs -0 prog

printf引数に対して型文字列を繰り返すので、グローバル拡張の各ファイル名に対して、-fファイル名をNULL文字で印刷して区切ります。xargs次にそれを読み、パラメータに変換しますprog。これは、--一部の実装のprintfフォーマット文字列に主な問題があるため必要です。-あるいは、標準人-に置き換えることもできます。\055

原則とラケシュの答え代わりにワイルドカード拡張を直接使用してください。

答え2

zshPこれでグローバル修飾子があります。

以前のバージョンでは、いつでも次のものを使用できます。

f=(*.txt)
prog -f$^f

$^f作るrcexpandparamオプション拡張の場合、配列は$fシェルと同じ方法で拡張されますrc

rc(または)からzsh -o rcexpandparam

f=(*.txt)
prog -f$f

prog -fa.txt -fb.txtcsh(または中括弧拡張をサポートする他のシェル)で作成するのと少し似ていますprog -f{a.txt,b.txt}

(2つの引数を渡すのではなく、*.txt(P:-f:)ファイル名がオプションに付けられていることが異なります。標準APIを使用してオプションを解析するすべてのコマンドを含む多くのコマンドは、引数をオプションに渡す方法の両方をサポートします。)-ffile.txt-f file.txtgetopt()

fish次のように配列を拡張することもできます。

set f *.txt
prog -f$f

ではbash、次のようにシミュレートできます。

f=(*.txt)
prog "${f[@]/#/-f}"

そしてksh93

f=(*.txt)
prog "${f[@]/*/-f\0}"

For-fとそのfile.txts が別々の引数として渡される別のオプションは、zsh配列圧縮演算子を使用することです。

o=-f f=(*.txt); prog ${o:^^f}

必要に応じて-gこの範囲を拡張できます。偶数のtxtファイルがあるとします。

o=(-g '') f=(*.txt); prog ${o:^^f}

-g両方のファイルのオプションが一度に渡されます。あなたが得るものと似ています:

printf -- '-g\0%s\0%s\0' *.txt | xargs -r0 prog

答え3

Bashを使って以下を試してください。

args=()
for f in important-files/*.txt
do
    args+=(-f "$f")
done
prog "${args[@]}"

これは、スペースを含むファイル名だけでなく、単一引用符、二重引用符または改行文字を含むファイル名にも適用されます。

インタラクティブで使いやすいです。

対話型の使用を容易にするには、関数を定義します。

progf() { args=(); for f in  "$@"; do args+=(-f "$f"); done; prog "${args[@]}"; }

この機能は次のように使用できます。

progf important-files/*.txt

関数定義を永久に作成するには、~/.bashrcファイルに入れます。

答え4

一つ。これを行う方法は、GNU find / xargs Duoを使用することです:

cd important-files && \
find . -name '*.txt'  -printf '-f\0%p\0' | xargs -0 -r  prog

関連情報