標準のUnixコマンドラインツール(grep、cut、sedなど)はすべて一度に1行ずつ実行されます。ほぼいつもそうです。本当に良いです。
しかし、いくつかのpostgresql遅いクエリログを解析しようとしています。各項目には、先頭(日付/時刻、期間)にいくつかの内容があり、その後にSQLクエリがあります。 SQLクエリには改行がある可能性があるため、ログファイルの各「アイテム」は1行以上にすることができます。なぜなら、クエリの改行はエスケープされず、ログファイルに直接入力されるからです。 1行= 1ログファイル項目になるように、どのような方法でもこの行を「マージ」したいと思います。現在、アイテム全体が1行にある場合もあり、アイテムが最大10行にわたって分散している場合もあります。
このファイルを「線形化」できるUnixツールはありますか? (PCRE)正規表現を提供し、それに基づいて行/標準入力を分割します。この正規表現の間のすべての実際の改行は、"\n"
私が指定できるものに置き換える必要があります。
Perlを使用してこれを行うライナーがあるかもしれませんが、私のプログラムを作成する前に、誰かがすでにこのプログラムを作成していることを確認したかったのです。
修正する:サンプルデータを提供できますが、一般的な質問を知りたいです。 SQL Serverでは、複数行のログファイルを生成できます。すべてのファイルを改行で区切られたunix-yスタイルファイルに変換する一般的なソリューションが必要です。
答え1
gawkを使用すると、PCRE式(のサブセット)をレジスタ区切り記号(RS
)として使用し、他の出力レジスタ区切り記号(ORS
)を定義してそれを置き換えることができます\n
。
例:
gawk 'BEGIN {RS="[ ]*;\n"; ORS="\n===\n"}
{gsub("\n","\\n"); print} '
この例では、次のようになります。
[ ]*;\n
レジスタは入力から次のように区切られます。- レジスタは出力で「\n===\n」に区分されます。
答え2
ログファイルを1行ずつ解析し、すべての\ nを抑制します。最初の項目を除いて新しい項目が表示されたら、最初に\ nを書きます。
言われましたが、Each entry has some stuff at the start (datetime, duration)
例を挙げませんでした。わかりました。名前をNEW_ENTRYにします。変更してください。
inStatement=0
cat logfile | while read -r line; do
if [[ ${inStatement} = 0 ]]; then
inStatement=1
else
[[ ${line} = NEW_ENTRY* ]] && echo
fi
echo -n "${line} "
done
echo