Konvertieren der Unix-Epochen-Zeitstempelspalte in jeder Zeile mit sed oder awk

Konvertieren der Unix-Epochen-Zeitstempelspalte in jeder Zeile mit sed oder awk

Ich habe eine Datei mit den folgenden Eingabebeispieldaten:

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

Die erste Spalte ist der Unix-Epochen-Zeitstempel, den ich in ein für Menschen lesbares Format konvertieren muss. Außerdem möchte ich, dass die Daten wie folgt abgegrenzt werden

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

ich habe versucht, Trennzeichen mit sed 's/ {1,}/|/g' hinzuzufügen und das Datum mit date -d @1137921146.499 zu konvertieren. Aber ich kann diese beiden nicht in einem Befehl zusammenfassen.

Antwort1

Sie können das Awk-Programm wie folgt verwenden:

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

Der Kern besteht darin, die Funktion strftime zu verwenden, um die Epoche in das Datumsformat zu konvertieren

Hier ist die Ausgabe:

#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: Oder Sie können ein implizites Ausgabetrennzeichen verwenden:

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

Antwort2

Verwenden Sie, was Sie bereits wissen:

  • GNU datekann einen Zeitstempel in ein formatiertes Datum umwandeln, indem es ihm Folgendes gibt @timestamp.
  • Wenn Sie Leerzeichen durch ersetzen, |erhalten Sie die gewünschte Ausgabe.

Dazu fügen wir hinzu

  • GNU datekann eine Datei bearbeiten und Daten in einem Stapel konvertieren.

Um Daten mit GNU stapelweise zu konvertieren, datemüssen wir die Zeitstempel extrahieren und ihnen Folgendes voranstellen @:

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

Der sedAusdruck ersetzt jede Zeile durch das erste durch Leerzeichen getrennte Feld mit dem Präfix @.

Mit bash(und ksh93oder jeder Shell, die Prozessersetzungen versteht):

$ 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

Dann müssen wir die anderen Felder der Eingabedaten nehmen und die Trennzeichen ersetzen:

$ 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

Dann fügen wir diese beiden Dinge mit einem |„as“-Trennzeichen zusammen:

$ 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

Antwort3

Oder mit Ihrer Shell:

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

verwandte Informationen