次の構文のパラメータを必要とするプログラムがあります。
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'
...各ファイル名-f
がprog
。-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
以前のバージョンでは、いつでも次のものを使用できます。
f=(*.txt)
prog -f$^f
$^f
作るrcexpandparam
オプション拡張の場合、配列は$f
シェルと同じ方法で拡張されますrc
。
rc
(または)からzsh -o rcexpandparam
:
f=(*.txt)
prog -f$f
prog -fa.txt -fb.txt
csh(または中括弧拡張をサポートする他のシェル)で作成するのと少し似ていますprog -f{a.txt,b.txt}
。
(2つの引数を渡すのではなく、*.txt(P:-f:)
ファイル名がオプションに付けられていることが異なります。標準APIを使用してオプションを解析するすべてのコマンドを含む多くのコマンドは、引数をオプションに渡す方法の両方をサポートします。)-ffile.txt
-f
file.txt
getopt()
fish
次のように配列を拡張することもできます。
set f *.txt
prog -f$f
ではbash
、次のようにシミュレートできます。
f=(*.txt)
prog "${f[@]/#/-f}"
そしてksh93
:
f=(*.txt)
prog "${f[@]/*/-f\0}"
For-f
とそのfile.txt
s が別々の引数として渡される別のオプションは、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