複数の値を含むオプションを使用するCLIツールがあります。構文は次のとおりです。
CLI -I path/to/file1 -I path/to/file2 ...
find
コマンド結果をこのCLIにどのように渡しますか?
参考までに
位置パラメータが複数ある場合:
CLI path/to/file1 path/to/file2 ...
私はできます:
find "dir" -name "pattern" -exec CLI {} \+
答え1
zsh
切り替えがオプションの場合は、次の方法で簡単に実行できます。
CLI **/pattern(P[-I])
ここで、P
glob修飾子は、P
一致する各ファイルのプレフィックスとしてパラメータを挿入するために使用されます。
kshスタイルのプロセス置換をサポートするGNUfind
やxargs
zshやbashなどのシェルを使用すると、次のこともできます。
xargs -xr0 -n100 -a <(find . -name pattern -printf '-I\0%p\0') CLI
100
ここでは、引数リストが単一の呼び出しに合うように十分に小さい偶数を選択しますCLI
。これがない場合は、xargs
リストを-I
次のファイルに分割できますp
。それでもその制約を満たさない場合は、少数の引数で実行するのではなく-n 100
終了します。-x
xargs
CLI
これに同意する場合は、CLI
次のこともできます。-Ipath/to/file
-I path/to/file
find . -name pattern -exec bash -c '
exec CLI "${@/#/-I}"' bash {} +
これは、必要に応じて複数回呼び出してパラメータサイズの制限を解決するためのものですが-exec cmd {} +
、bashは各パラメータにを追加するため、独自に実行された場合でもその制限に達する可能性があります。cmd
-I
cmd
ただし、そのプレフィックスは-I
すべてのファイルパスに追加されたプレフィックスと同じ長さであり、ここでは必要ではない./
ため、次の代わりに問題を完全に回避することもできます。bash
./
-I
find . -name pattern -exec bash -c '
exec CLI "${@/#.\//-I}"' bash {} +
(.
それ自体(開始ファイル)が次のようになるとします。模様)。
上記の方法はシステムコールの制限zsh
を解決しようとせず、一度だけexecve()
実行されるか、CLI
まったく実行されません。zargs
自動ロード機能を使用してこの制限を解決できます。
CLI
ファイルごとに一度だけ呼び出すことが重要な場合は、-I file
最新バージョンのLinuxではスタックサイズの制限を増やすことlimit stacksize 100M
ができます(例:zshのデフォルト値8MiB)。execve()
制限はスタックサイズの制限に比例するためです。
答え2
CLI
出力からパラメータ配列を作成し、各ファイル名を前に付けてから、find
次のパラメータを使用して呼び出します。-I
CLI
#!/usr/bin/env bash
args=()
while IFS= read -r file; do
args+=( -I "$file" )
done < <(find "dir" -name "pattern" -print)
CLI "${args[@]}"
ファイル名に改行文字を含めることができる場合(質問の例とは異なり)、パラメータに追加して-d ''
GNUread
を使用find
してください。-print
-print0
上記の仮定の内容はargs[]
ARG_MAXを超えません。
答え3
最初の試みで、
find . -print | sed 's/^/-I /'| xargs echo
します。警告:ファイル名にスペースや特殊文字に関する問題がたくさんあります。