データ行を含むログがあります。
Mon Apr 20 03:15:18 EDT 2015: my|data|data|data
ログからデータを抽出して先行タイムスタンプを削除するスクリプトを作成しようとしています。
while read p
do
echo $p | sed "s/.* EDT $year: //g" > replay_message_$count.txt;
count=$((count+1));
done < $fileName
これで、ユーザーがパラメータを渡す.* EDT $year:
スキーマを使用しています。$year
年をパラメータとして渡さずにデータを抽出するには?
答え1
日付形式に常にスペースで区切られた6つのフィールドがあることがわかっている場合は、次のようにします。
cut -d ' ' -f 7-
タイムスタンプが常に30文字を占めていることがわかっている場合は、次のものを使用できます。
cut -c 31-
タイムスタンプが数字、コロン、スペースで終わり、データにこのパターンが含まれていない場合は、次のようになります。
sed 's/.*[0-9]: //'
より具体的な要件がある場合は提出してください。
答え2
while
これはスクリプトのすべてのループを置き換えることです。
awk '{print substr($0, 31)>("replay_message_" NR-1 ".txt")}' file
仕組み:
print substr($0, 31)
これにより、行の最初の30文字を除くすべての文字が印刷されます。
>("replay_message_" NR-1 ".txt")
これにより、印刷された内容が行番号で指定されたファイルに転送されます。
awk コマンドが完了すると、次の一連のファイルがディレクトリに表示されます。
$ ls -1 replay_message*
replay_message_0.txt
replay_message_1.txt
replay_message_2.txt
replay_message_3.txt
タイムスタンプ長の変更に代わるもの
awk '{sub(/.* E[SD]T [[:digit:]]{4}: /, ""); print >("replay_message_" count++ ".txt")}' file
どのように動作しますか?
awk は、一度に 1 つのレコード (行) で暗黙的にファイルを読み込みます。各行に対して、次の操作を行います。
sub(/.* EDT [[:digit:]]{4}: /, "")
これにより、行の先頭のタイムスタンプが削除されます。
正規表現は、スペース、タイムゾーン(ESTまたはEDT)、スペース、年の4桁の数字、コロン、スペースを含むすべての項目と一致します。
あるいは、タイムスタンプに30文字しか必要でないことが保証されている場合は、より簡単な代替方法を使用できます。
sub(/.{30}/, "")
入力ファイルによって、状況に最も適したものが何であるかを判断する必要があります。
print >("replay_message_" count++ ".txt")
これにより、変更された行が数字を含むファイルに書き込まれます
count
。これは書き込みごと++
にcount
増加します。