web-dev-qa-db-ja.com

リモートマシンでgrepを実行し、それらの単語を含む行を出力する方法は?

このディレクトリの下のmachineBにいくつかのログファイルがあります/opt/ptd/Logs/以下に示すように-私のログファイルはかなり大きいです。

david@machineB:/opt/ptd/Logs$ ls -lt
-rw-r--r-- 1 david david  49651720 Oct 11 16:23 ptd.log
-rw-r--r-- 1 david david 104857728 Oct 10 07:55 ptd.log.1
-rw-r--r-- 1 david david 104857726 Oct 10 07:50 ptd.log.2

machineB内のすべてのログファイルを解析して特定のパターンを探し、それらのパターンを含む行を出力する一般的なシェルスクリプトを記述しようとしています。すべてのsshキーですべてを設定するmachineAから以下のシェルスクリプトを実行します。つまり、machineAからmachineBのログファイルをリモートでgrepする必要があります。

#!/bin/bash

wordsToInclude="hello,animal,atttribute,metadata"
wordsToExclude="timeout,runner"

# now grep on the various log file for above words and print out the lines accordingly

つまり、wordsToInclude変数にカンマで区切られた単語が含まれます-ログにhello Wordが含まれている場合は、その行を印刷し、animal Wordを含む行も印刷します。同様に、attributemetadataの単語を使用します。

また、wordsToExclude変数にコンマで区切られた単語が含まれます-行のいずれかにそれらの単語が含まれている場合は、それらの行を出力しません。

私は今のところ、単語を保存するために上記のフォーマットを使用しますが、それ以上のフォーマットでも問題ありません。 wordsToIncludeおよびwordsToExclude変数に単語の長いリストを含めることができるため、これらの変数に単語を格納します。

変数の小さなセットでgrepを実行する方法を知っています。 machineBのコマンドラインから直接grepを実行する必要がある場合は、次のようにします-

grep -E 'hello|animal|atttribute|metadata' ptd.log | grep -v 'timeout'

しかし、これをシェルスクリプトでどのように組み合わせれば、machineAからmachineBでリモートssh grepを実行できるかわかりません。

3
david

他の形式を使用する場合は、次の点を考慮してください。

inc="hello|animal|atttribute|metadata"
exc="timeout|runner" 
ssh machineB "grep -E '$inc' path/ptd.log | grep -vE '$exc'"

より速い代替

ログファイルが大きく、派手な正規表現とは対照的に、固定単語を探している場合は、このアプローチを検討することをお勧めします。

inc='hello
animal
atttribute
metadata'

exc='timeout
runner'

ssh office "grep -F '$inc' ptd.log | grep -vF '$exc'"

各Wordを別々の行に置くことで、固定文字列に対してgrepの-F機能を使用できます。これにより、正規表現処理がオフになり、処理が速くなります。

8
John1024

可能ではないように見えるかもしれませんが、grep-fオプションを使用して、それらの単語のリストを使用できます。ただし、環境変数にあり、適切なファイルではありません。トリックは、grepをだまして、それらが次のようなファイルからのものであると考えるようにすることです。

$ ssh machineB 'grep -f <(echo $wordsToInclude|tr , "\n") file1 file2 file3'

これにより、machineBのsshを介してgrep ...コマンドがリモートで実行されます。変数$wordsToIncludeを受け取り、コンマを行末文字に切り替えます(,-> \n)。この単語のリストは、-fスイッチを介してgrepに送られます。

これを除外リストで実行するには、パイプを介して最初のgrepの後に2番目のgrepとして追加するだけです。

$ ssh machineB 'grep -f <(echo $wordsToInclude|tr , "\n") \
    file1 file2 file3 | grep -vf <(echo $wordsToExclude)'
2
slm

SSHは次のようなコマンドで実行されます。

ssh Host command

またはあなたの場合:

ssh -t machineB "grep -E \"$wordsToInclude\" ptd.log | grep -v \"$wordsToExclude\""

-tは、「ioctlエラー」を防ぎます。 @ John1024の this answer で指定されているように、速度を上げるためにgrepの固定語を使用することもお勧めします。次のように、各Wordをそれぞれの行に追加します。

wordsToInclude='hello
animal
atttribute
metadata'

wordsToExclude='timeout
runner'

そして、-Fをgrepのオプションに追加します。

1
Aiden Woodruff