2016-11-29 4 views
0

私は何度も試みてきましたが、さまざまな方法を試しましたが、これを動作させるように見えません。私は、Pythonスクリプトを実行しようとしていると、ファイルに含まれているかどうかを確認するために出力をgrepしていない場合、私はそれをファイルに追加したい。 >>それはどちらかの標準出力をピックアップしないため動作しません - そして、stdoutとそのよう -プログラムのstdoutがファイル内にあるかどうかを確認する方法は?

$./scan_network.py 22 192.168.1.1 192.168.1.20 | if ! grep -q - ./results.log; then - >> results.log; fi 

は、私はそれがのMacOSのgrepは理解していないことを理解しています。私は何をすべきか分かりません。

先に述べたように、主な目的は、スクリプトの出力をファイルと照合し、IPアドレスがファイル内に見つからない場合は追加する必要があることです。

編集:

results.logは現在空のファイルです。 scan_network.pyの出力は今のところ192.168.1.6になります。別のネットワーク上で実行すると、出力は10.234.xyの範囲の例で多数のアドレスになります。ここで、xとyは0〜255の任意の数値です。

+2

"grepはファイルに含まれているかどうかを確認するための出力"は、grepの意味が分からないため、解析が非常に難しいです。 (私は "grep"の意味を知っていますが、明らかに同じではありません)。*あなたが "出力内の各行をチェックして、ファイル内にすでに見つかっているかどうかを確認する"という意味です。あれは正しいですか?もしそうなら、あなたの実際の問題は、 "現在ファイルに入っていないプログラムの出力にあるすべての行を見つけ、それをファイルに追加する"ことです。これは簡単に解決できますが、grepユーティリティは使用しません。 – rici

+0

これは、@ aiを見る正しい方法です。私はps auxなどのコマンドを実行し、grepを通して配管することに慣れていますので、この方法についてどうやって行くのかは分かりませんでした。 – isema

+1

macosでは 'grep -f/dev/stdin -q。/ results.log'を使って標準入力からパターンを読み込むことができます。 – alvits

答えて

3

一つの簡単な解決策は、新しいログファイルに、ログファイルとプログラムの出力をマージすることである。

sort -u <(./scan_network.py 22 192.168.1.1 192.168.1.20) results.log > newresults.log 

-uフラグを出力から除去する重複行を引き起こしますので、各行の1つだけを取得します。

これは、行を並べ替える(アルファベット順に並べ替える)という副作用があります。必要に応じて順序を保持することは可能ですが、より複雑になります。

合理的に現代的なgnu sortでは、「バージョン番号」ソートを使用できます。ソートは、論理的な順序でIP番号を保持するという妥当な作業です。 -Vフラグを使用してこれを行うことができます。または、sort -u -t. -k1,1n -k2,2n -k3,3n -k4,4n ...で個別にオクテットを並べ替えることもできます。あるいは、辞書編集の順序で暮らすこともできます。最初のオクテットだけを調べるため、-nを標準の数値ソートに使用しないでください。これは、同等の2つの行が重複と見なされるため、-uオプションとの不幸なやりとりをします。数値ソートは数字の接頭辞のみを考慮するので、重複した重複が多数あります。

+0

それはちょうど必要に応じて働いてくれてありがとう。 – isema

0

スクリプトが1行のテキストを返すと仮定すると変数に出力を格納し、その文字列をgrepすることができます。例えば:

logfile="results.log" 

# save output to a shell variable 
str=$(./scan_network.py 22 192.168.1.1 192.168.1.20) 

# don't call grep twice for the same pattern  
grep=$(grep -F "$str" "$logfile") 

# append if grep results are empty 
if [[ -z "$grep" ]]; then 
    echo "$grep" >> "$logfile" 
fi 
+0

このスクリプトは、ポート22で応答するすべてのホストのIPアドレスを含む複数の行を表示します。 – isema

+0

@isemaこれは、実際の入出力を投稿する必要がある理由です。他の人が「自分のデータがどのように見えるか」と思うのは妥当ではありません。 –

1

あなたは、ソート、よく作品(単に真のコンポーネントごとの数値IPアドレスのソートに-Vを使用してノートないのMacOS上のオプション、残念ながらあり)rici's helpful answerログファイルを、書き換え気にしない場合。 [1]

ここ代替のみ既存の行の順序を変更せずに、その場で、必要に応じて既存のログファイルに追加していることです:

grep -f results.log -xFv <(./scan_network.py 22 192.168.1.1 192.168.1.20) >> results.log 

注:これは./scan_network.pyの出力はラインベースであることを想定しています。パイプをtrに変更して、必要に応じてラインベースの出力に変換します。

  • -fは、指定されたファイルの各行を別々の検索語として扱います。ここでは、任意の語句の一致が全体一致と見なされます。フル
  • -Fを実行中
  • -xマッチラインリテラルマッチング(正規表現などの検索用語を解釈することはありません)
  • -vだけない試合

正味の効果を行う行を出力results.logにまだ存在していない./scan_network.py ...によって出力された行だけがresults.logに追加されていることです。

しかし、パフォーマンスが悪くなる可能性がありますので、特にログファイルが増え続ける場合や、ログをIPアドレスで並べ替える場合には、riciの方が望ましいかもしれません。

  • GNUおよびBSD/MacOSのgrepの両方が必要に応じて標準入力から入力を受け入れ、それを注意するためのプレースホルダとして-を受け入れる:あなたはを試した何については


    grepはデフォルトでstdinから入力を読み込むため、このオペランドは必要ありません。これとは対照的に

  • 、唯一GNUgrepは、-fからオプション引数として、すなわち、検索用語に適用するを含むファイルを-を受け付けます。
    BSD/macOSには、明示的なファイル名、プロセス置換(上記のように)、ピンチではstdinを参照するのに/dev/stdinが必要です。上記のコマンドのように、既存のログファイルの内容が検索語(-fに渡される)として機能しなければならない、と./scan_network.py ...出力が決定するために、入力として使用する必要があります。

  • 検索の論理が逆転しなければなりませんログファイルに既にでない行が-v)ではありません。

  • コンテキストに応じて、または標準出力を標準入力表すため-を使用して、コマンドのみ引数として働く単なる大会ですので、if ...; then - >> results.logと標準出力の出力を参照するためにあなたの試みは動作しないことができる、-理由常にコマンド名と解釈されます。

  • あなたがgrep -qを使用する場合は、標準出力が定義であるがを抑制するので、(あなたがパイプを使用した場合でも)に合格するものは何もありません。


[1]のMacOSの(OSのXさん)sortは(IPがあまりにアドレスに適用することができる)、ソートコンポーネントごとのバージョン番号のためない支持-Vを行います。 MacOSの10.12のようv5.93 - - -Vのサポートを以前からMacOSのsortGNUsortであっても、それは古代一つです。

+0

あなたがこれを説明した方法は私には意味があります。あなたの提案と、いずれかの方がパフォーマンスの点で優れているというriciの提案の間には考えていますか? – isema

+0

@isema:データが多ければ多いほど、riciのアプローチは優れていると思いますが、小さな入力セットとログファイルでは問題にならないかもしれません。あなたのログファイルが増え続けるなら、私はriciのアプローチに行きます。いくつかの実験を実行する場合は、結果を共有してください。 – mklement0

関連する問題