0

問題:特定のパラメータについて、ノードの事前チェックステータスと事後チェックステータスのファイルを比較します。

コミュニティの助けを借りて、「Node-ID」(たまたま一意であり、ファイルからも抽出される)に基づいて、前後のディレクトリからファイルから情報を抽出する次のソリューションを作成しました。Pre / postフォルダーからデータを抽出した後、node-idに基づいてフォルダーを作成し、ファイルをフォルダーにダンプしました。

データを抽出するためのマイコード(データはPreフォルダーとPostフォルダーから抽出されます)

FILES=$(find postcheck_logs -type f -name *.log)
for f in $FILES
do
    NODE=`cat $f | grep -m 1 ">" | awk '{print $1}' | sed 's/[>]//g'`  ##Generate the node-id
    echo "Extracting Post check information for " $NODE 
    mkdir temp/$NODE-post  ## create a temp directory
    cat $f | awk 'BEGIN { RS=$NODE"> "; } /^param1/ { foo=RS $0; } END { print foo ; }' > temp/$NODE-post/param1.txt ## extract data
    cat $f | awk 'BEGIN { RS=$NODE"> "; } /^param2/ { foo=RS $0; } END { print foo ; }' > temp/$NODE-post/param2.txt
    cat $f | awk 'BEGIN { RS=$NODE"> "; } /^param3/ { foo=RS $0; } END { print foo ; }' > temp/$NODE-post/param3.txt
done

この後、私は次のような構造になります。

/Node1-pre/param1.txt
/Node1-post/param1.txt

等々。

今、私は比較$NODE-pre$NODE-postファイルに固執しています、

再帰的なgrepを使用してそれを実行しようとしましたが、適切な方法が見つかりません。diffを使用してこれらのファイルを比較するための最良の方法は何ですか?

さらに、上記のデータ抽出プログラムは非常に遅いと思います。私はそれがそうするための最良の方法(最小限のリソースを使用する)ではないと信じています。助言がありますか?

4

1 に答える 1

3

の任意のインスタンスで質問を見てくださいcat one-file—代わりにパイプラインの次のコマンドでI/Oリダイレクトを使用できます。

次の方法ですべてをより簡単に行うことができます。

for f in $(find postcheck_logs -type f -name *.log)
do
    NODE=$(sed '/>/{ s/ .*//; s/>//g; p; q; }' $f)  ##Generate the node-id
    echo "Extracting Post check information for $NODE" 
    mkdir temp/$NODE-post
    awk -v NODE="$NODE" -v DIR="temp/$NODE-post" \
        'BEGIN { RS=NODE"> " }
         /^param1/ { param1 = $0 }
         /^param2/ { param2 = $0 }
         /^param3/ { param3 = $0 }
         END {
             print RS param1 > DIR "/param1.txt"
             print RS param2 > DIR "/param2.txt"
             print RS param3 > DIR "/param3.txt"
             }' $f
done

NODEの検索プロセスは、単一のsedコマンドで実行するよりもはるかに優れているため、どこでも引用符で囲むのではなく、cat | grep | awk | sed使用することを計画する必要があります。$(...)

ログファイルの主な処理は1回実行する必要があります。1つのawkコマンドで十分です。スクリプトは変数(NODEとディレクトリ名)に渡されます。BEGINがクリーンアップされます。以前の$ノードはおそらくあなたが意図したものではありませんでした。主なアクションは非常に似ています。それぞれが関連するパラメータ名を探し、それを適切な変数に保存します。最後に、保存された値をRSの値で装飾された関連ファイルに書き込みます。セミコロンは、1行に複数のステートメントがある場合にのみ必要です。この拡張スクリプトには、1行に1つのステートメントしかありません。オリジナルより大きく見えますが、それは私が垂直方向のスペースを使用しているからです。


前後のファイルの比較に関しては、知りたいことに応じて、さまざまな方法で比較できます。POSIXに準拠している場合diff(おそらくそうです)、次を使用できます。

diff -r temp/$NODE-pre temp/$NODE-post

2つのディレクトリの内容の違いがある場合は、それについて報告します。または、手動で行うこともできます。

for file in param1.txt param2.txt param3.txt
do
    if cmp -s temp/$NODE-pre/$file temp/$NODE-post/$file
    then : No difference
    else diff temp/$NODE-pre/$file temp/$NODE-post/$file
    fi
done

明らかに、これを「ノードごとに」ループでラップできます。また、それを行う必要がある場合は、findコマンドの出力を(元のコードのように)変数にキャプチャして、その操作を繰り返す必要がないようにする必要があります。

于 2012-07-22T15:04:42.583 に答える