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個のディレクトリ名のリストが表示されますが、これも必要なものではありません。
あと少しです。最後のコマンドでは、-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
で実行します。
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
ちょうど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 {}
コマンドでも同じことが起こります。 {}
は、プレパイプコマンドの内容に置き換えられます。