次のコマンドを実行しようとしています。
find . -iname '.#*' -print0 | xargs -0 -L 1 foobar
ここで、「foobar」は、私の.bashrcファイルで定義されているエイリアスまたは関数です(私の場合、これは1つのパラメーターを受け取る関数です)。どうやらxargsはこれらを実行できるものとして認識していません。これを改善する賢い方法はありますか?
インタラクティブシェルだけがエイリアスについて知っているので、xargs
をフォークせずにエイリアスを実行してみませんか?
find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done
ファイル名に改行が含まれていないことが確実な場合(ええと、なぜ改行するのでしょうか?)、これを次のように簡略化できます。
find . -iname '.#*' -print | while read -r i; do foobar "$i"; done
または、デフォルトのディレクトリはfind -iname '.#*' | ...
であり、デフォルトのアクションは.
であるため、-print
だけでもかまいません。
もう1つの選択肢:
IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done
単語は改行でのみ分割されることをBashに伝えます(デフォルト:IFS=$' \t\n'
)。ただし、これには注意する必要があります。一部のスクリプトは、変更された$IFS
にうまく対応しません。
Bashを使用すると、次のようにエイリアス(または関数)に渡される引数の数を指定することもできます。
alias myFuncOrAlias='echo' # alias defined in your ~/.bashrc, ~/.profile, ...
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0
echo arg1 arg2 | xargs bash -cil 'myFuncOrAlias "$@"' arg0
xargs
は、パラメータとして指定されたprogramをexec
できることを期待しているため、これは機能しません。
あなたの場合のfoobar
は単なるbash
エイリアスまたは関数であるため、実行するプログラムはありません。
bash
によって返されるファイルごとにfind
を開始する必要がありますが、次のように小さなシェルスクリプトを記述できます。
#!/bin/bash
. $(HOME)/.bashrc
func $*
次に、そのスクリプトの名前をパラメーターとしてxargs
に渡します。
私は通常次のようなfindを使用します:
find . -iname '' -exec cmd '{}' \;
'{}'はファイル名に置き換えられ、\;実行チェーンを終了するために必要です。ただし、それが関数で機能しない場合は、bashを介して実行する必要がある場合があります。
find .. |sed -e "s/.*/cmd '&'/"|bash
Findは各ファイルを1行に出力し、sedはこれにコマンドのプレフィックスを付けて、bashにパイプして実行します。最初に| bashをスキップして、何が起こるかを確認してください。
試してみてください
find . -iname '.#*' -print0 | xargs -0 -L 1 $(foobar)