sed または awk を使用して各行の Unix エポック タイムスタンプ列を変換する

sed または awk を使用して各行の Unix エポック タイムスタンプ列を変換する

次の入力サンプルデータを含むファイルがあります。

1137921146.499 180900 61.153.158.197 1409 
1137921158.698 181622 61.153.158.197 1409
1137921758.163 180026 221.226.124.114 1374
1137921802.016 179485 121.13.128.132 1409

1列目はUNIXエポックタイムスタンプであり、これを人間が読める形式に変換する必要があり、さらにデータを次のように区切る必要があります。

Sun Jan 22 01:12:26 PST 2006|180900|61.153.158.197|1409   
Sun Jan 22 01:12:38 PST 2006|181622|61.153.158.19|1409

sed 's/ {1,}/|/g' を使用して区切り文字を追加し、date -d @1137921146.499 を使用して日付を変換しようとしました。しかし、これら 2 つを 1 つのコマンドにまとめることはできません。

答え1

awk プログラムは次のように使用できます。

awk '{ print strftime("%c",$1)"|" $2"|"$3"|"$4 }' file

核となるのは、strftime関数を使用してエポックを日付形式に変換することです。

出力は次のとおりです。

#awk '{ print strftime("%c",$1)"|" $2"|"$3"|"$4 }' file
Sun Jan 22 10:12:26 2006|180900|61.153.158.197|1409
Sun Jan 22 10:12:38 2006|181622|61.153.158.197|1409
Sun Jan 22 10:22:38 2006|180026|221.226.124.114|1374
Sun Jan 22 10:23:22 2006|179485|121.13.128.132|1409

PS または、暗黙の出力区切り文字を使用することもできます。

awk  'BEGIN { OFS="|"} {$1= strftime("%c",$1) }1' file

答え2

すでに知っていることを使って:

  • GNU はdate、 を与えることでタイムスタンプをフォーマットされた日付に変換できます@timestamp
  • スペースを に置き換えると、|必要な出力が得られます。

これに我々は付け加える

  • GNU はdateファイルに対して操作を実行し、日付を 1 回のバッチで変換する場合があります。

GNU を使用して日付を一括変換するには、dateタイムスタンプを抽出し、次の接頭辞を付ける必要があります@

$ sed 's/^\([^ ]*\).*$/@\1/' data.in
@1137921146.499
@1137921158.698
@1137921758.163
@1137921802.016

このsed式は、各行を、先頭に . が付いた最初のスペース区切りフィールドに置き換えます@

bash(および、ksh93またはプロセス置換を認識する任意のシェル)を使用する場合:

$ date -f <( sed 's/^\([^ ]*\).*$/@\1/' data.in )
Sun Jan 22 10:12:26 CET 2006
Sun Jan 22 10:12:38 CET 2006
Sun Jan 22 10:22:38 CET 2006
Sun Jan 22 10:23:22 CET 2006

次に、入力データの他のフィールドを取得して区切り文字を置き換える必要があります。

$ cut -d ' ' -f 2- data.in | tr ' ' '|'
180900|61.153.158.197|1409
181622|61.153.158.197|1409
180026|221.226.124.114|1374
179485|121.13.128.132|1409

次に、これら 2 つを as 区切りで貼り付けます|

$ paste -d '|' <( date -f <( sed 's/^\([^ ]*\).*$/@\1/' data.in ) ) <( cut -d ' ' -f 2- data.in | tr ' ' '|' )
Sun Jan 22 10:12:26 CET 2006|180900|61.153.158.197|1409
Sun Jan 22 10:12:38 CET 2006|181622|61.153.158.197|1409
Sun Jan 22 10:22:38 CET 2006|180026|221.226.124.114|1374
Sun Jan 22 10:23:22 CET 2006|179485|121.13.128.132|1409

答え3

またはシェルで:

while read timestamp pid ip port; do
  echo "$(date -d @$timestamp)|$pid|$ip|$port"
done <yourfile

関連情報