Unix系コマンドのワイルドカード(*)にご注意?! find/xargsを使おう [Solaris]
久しぶりにSolarisのコマンドでハマリましたので、Tipsで残しておきます。
ログファイルを格納しているディレクトリに対して、ls -l *.logって実行すると「Argument list too long.」 や「引数が多すぎます 」、「引数リストが長すぎます」などとエラーになります。
これは、ワイルドカード(*)がシェルの内部処理によって展開され、コマンドラインのサイズをオーバーしてしまうかです。例えば、a.logとb.logの2つのファイルが存在し、ls -l *.logとすると、ファイル名展開により、ls -l a.log b.logになります。シェルが展開した文字数は、OS毎に制限があり、solarisでは1MB(1,048,320)、Linux(Ubuntu10.10)では2MB(2,097,152)になっています。
使っているOSのARG_MAXを参照すれば、コマンドラインサイズがわかります。
% getconf ARG_MAX
では、コマンドラインサイズを超えてしまうls -l *.logをどのようにすれば、できるのでしょうか。
①findを使う
find . -name \*.log -exec ls -l {} \;
(-execでは1ファイル毎にls -lが行われるため、非常に遅い)
②find+xargsを使う
find . -name \*.log | xargs ls -l
③grepを使う
ls -l | grep .log
lsで表示できたものを削除したい場合には、rm *.logとしたいところですが、これもエラーになります。こんなときは、xargsを使うと効率的にrmができます。
①xargsを使ってrmする
ls | grep .log | xargs rm
または
find . -name \*.log | xargs rm
②findを使ってrmする
find . -name \*.log -exec rm {} \;
(1ファイル毎にrmが行われるため、非常に遅い)
同様にtarでまとめたい時もxargsを使うと効率的に可能です。
①xargsを使ってtarする
ls | grep .log | xargs tar rvf /tmp/logs.tar
または
find . -name \*.log |xargs tar rvf /tmp/logs.tar
②findを使ってtarする
find . -name \*.log -exec tar rvf /tmp/logs.tar {} \;
(1ファイル毎にrmが行われるため、非常に遅い)
最近では、コマンドラインサイズも大きくなってきているので、エラーになる確率も減っていると思います。
xargsをうまく使うことで、処理時間の短縮が図れますので、是非xargsをご利用ください。
ログファイルを格納しているディレクトリに対して、ls -l *.logって実行すると「Argument list too long.」 や「引数が多すぎます 」、「引数リストが長すぎます」などとエラーになります。
これは、ワイルドカード(*)がシェルの内部処理によって展開され、コマンドラインのサイズをオーバーしてしまうかです。例えば、a.logとb.logの2つのファイルが存在し、ls -l *.logとすると、ファイル名展開により、ls -l a.log b.logになります。シェルが展開した文字数は、OS毎に制限があり、solarisでは1MB(1,048,320)、Linux(Ubuntu10.10)では2MB(2,097,152)になっています。
使っているOSのARG_MAXを参照すれば、コマンドラインサイズがわかります。
% getconf ARG_MAX
では、コマンドラインサイズを超えてしまうls -l *.logをどのようにすれば、できるのでしょうか。
①findを使う
find . -name \*.log -exec ls -l {} \;
(-execでは1ファイル毎にls -lが行われるため、非常に遅い)
②find+xargsを使う
find . -name \*.log | xargs ls -l
③grepを使う
ls -l | grep .log
lsで表示できたものを削除したい場合には、rm *.logとしたいところですが、これもエラーになります。こんなときは、xargsを使うと効率的にrmができます。
①xargsを使ってrmする
ls | grep .log | xargs rm
または
find . -name \*.log | xargs rm
②findを使ってrmする
find . -name \*.log -exec rm {} \;
(1ファイル毎にrmが行われるため、非常に遅い)
同様にtarでまとめたい時もxargsを使うと効率的に可能です。
①xargsを使ってtarする
ls | grep .log | xargs tar rvf /tmp/logs.tar
または
find . -name \*.log |xargs tar rvf /tmp/logs.tar
②findを使ってtarする
find . -name \*.log -exec tar rvf /tmp/logs.tar {} \;
(1ファイル毎にrmが行われるため、非常に遅い)
最近では、コマンドラインサイズも大きくなってきているので、エラーになる確率も減っていると思います。
xargsをうまく使うことで、処理時間の短縮が図れますので、是非xargsをご利用ください。