web-dev-qa-db-ja.com

パイプされたxargsの後のパイプコマンド

HP-UX ***** B.11.23 U ia64 ****無制限ユーザーライセンス

find . -type d -name *log* | xargs ls -la

ディレクトリ名(ディレクトリ名にlogを含むもの)に続いて、そのディレクトリ内のすべてのファイルが表示されます。

ディレクトリ/var/opt/SID/application_a/log//var/opt/SID/application_b/log//var/opt/SID/application_c/log/などには、ログファイルが含まれています。

ls -latr | tail -2を使用して通常見つけているlsコマンドで2つの最新のログファイルのみを一覧表示したい。

出力はこのようなものでなければなりません。

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2では、上記の結果は得られません。取得するのは、find . -type d -name *log* | xargs ls -laコマンドの最後の2つのファイルのリストです。

パイプされたxargsの後にコマンドをパイプできますか?上記の形式で結果のファイルのリストを取得するには、他にどのようにクエリを実行しますか?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

現在のディレクトリ内の/var/opt/SIDである10個のディレクトリ名のリストが表示されますが、これも必要なものではありません。

44
anotherperson1

あと少しです。最後のコマンドでは、-Iを使用してlsを正しく実行できます

-I replace-str

    Initial-arguments内のreplace-strの出現箇所を標準入力から読み取った名前に置き換えます。また、引用符で囲まれていない空白は入力項目を終了しません。代わりに、区切り文字は改行文字です。 -xおよび-L 1を意味します。

だから、

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

echoは、findで見つかったディレクトリをls | tailで実行します。

68
fredtantini

GNU Parallelはこの種のタスクを簡単にします:

find . -type d -name "*log*" | parallel --tag "ls -la {} | tail -2"

GNU Parallelのフルインストールを実行したくない場合は、最小限のインストールを実行できます: http://git.savannah.gnu.org/cgit/parallel.git/tree/README

5
Ole Tange

ちょうどfredtantiniに加えて、一般的な説明として(ドキュメントが少しわかりにくいので):

xargs -I {}は、標準入力から '{}'文字を受け取り、パイプから入力されたものに置き換えます。これは、実際に{}を任意の文字の組み合わせで置き換えることができることを意味します(おそらく、好みのプログラミングフレーバーをより適切に適合させるため)。 xargs -I % sh -c "echo %"。常にxargs -I {}を使用する場合は、xargs -iに置き換えることができます。

sh -cは、次のコマンドを標準入力からではなく文字列から読み取るようにbash/Shellに指示します。したがって、sh -c "echo something"を書くことはecho somethingと同等です。

xargs -I {} sh -c "echo {}"は、sh -cで作成した入力echo {}を読み取ります。 {}をパイプから取得した引数に置き換えるように指示したので、それが起こります。

パイプを使わなくてもこれを簡単にテストできます。ターミナルで上記のコマンドを入力するだけです。次に書くものは何でもターミナルに出力されます(終了するにはCtrl-D)。

ls -la {}コマンドでも同じことが起こります。 {}は、プレパイプコマンドの内容に置き換えられます。

4
Borisu