Wie entferne ich den ersten Doppelpunkt ':' aus einem Zeitstempel?

10

Ich bin neu in der Programmierung !!

Kann jemand helfen, die :an der ersten Position in einem Zeitstempel zu entfernen ::29.06.2019 23:03:17

Derzeit versuche ich es mit awk / cut-Befehlen wie unten gezeigt:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2)"
echo "$TDS"


29.06.2019 23

Und die Ausgabe ist nicht das, was ich wollte! Ich möchte es als drucken 29.06.2019 23:03:17.

Manoj Kumar
quelle

Antworten:

14

Um das erste Zeichen abzuschneiden, können Sie auch Folgendes verwenden cut -c:

$ echo ":29.06.2019 23:03:17" | cut -c 2-
29.06.2019 23:03:17
pLumo
quelle
11

Verwenden

cut -d: -f2-

Anstatt von

cut -d: -f2

um etwas vom zweiten Feld bis zum Zeilenende zu bekommen:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2-)"
echo "$TDS"
Florian Diesch
quelle
8

awkist ein cooles Tool, mit dem Sie sehr komplexe Aufgaben lösen können. Aber für Ihre Frage würde ich mich lieber an die grundlegenden Fähigkeiten von Bash halten.

Für diese einfache Entfernung von Teilstringen würde ich Folgendes tun:

zehe="Logfile started :29.06.2019 23:03:17"
echo "${zehe#*:}"

Dies wird gedruckt:

29.06.2019 23:03:17

Als ich in Ihrer Position war und anfing, Programmieren und Bash zu lernen, habe ich viel von diesem Handbuch gelernt:

ABS - Advanced Bash-Scripting Guide

Weitere Beispiele und interessante Informationen zu Ihrem Problem finden Sie hier unter "Entfernen von Teilstrings".

Hannes Morgenstern
quelle
3
+1 Das! Da die Frage mit "bash" gekennzeichnet ist, sollte in Betracht gezogen werden, die großartigen (wenn auch oft recht undurchsichtigen) Möglichkeiten von bash zu bevorzugen, Zeichenfolgen zu bearbeiten, die viel schneller sind als das Laden externer Tools.
Rexkogitans
2
@rexkogitans Da wir bereits grep oder awk aufrufen, um eine Datei zu analysieren, wird bash nicht schneller sein. In der Tat ist es langsam, wann immer Sie eine Datei-Bash analysieren müssen. Alle Muscheln sind langsam und Bash ist langsamer als die meisten anderen. Trotzdem sind die String-Manipulationsfunktionen der Shell in der Tat oft der beste Ansatz, aber nur, wenn Sie die Eingabe bereits als Variable haben.
Terdon
8

Hier ist eine sedLösung:

$ echo ':29.06.2019 23:03:17' | sed 's/^://'
29.06.2019 23:03:17

Der Befehl sed 's/^://'ersetzt sdas Doppelpunktzeichen :am Anfang ^jeder Zeile durch die leere Zeichenfolge //.

Hier ist eine knifflige awkLösung, bei der wir das ^:oben beschriebene Feldtrennzeichen auf ändern und das zweite Feld (jeder Zeile) ausgeben:

$ echo ':29.06.2019 23:03:17' | awk -F'^:' '{print $2}'
29.06.2019 23:03:17

Die Aufgabe könnte auch mit grep( Erklärung ) erledigt werden , wahrscheinlich könnte dies die schnellste Lösung für große Datenmengen sein:

$ echo 'Logfile started :29.06.2019 23:03:17' | grep -Po '^Logfile started :\K.*'
29.06.2019 23:03:17

Oder verarbeiten Sie die Datei direkt mit dem folgenden Befehl, wobei die Einschränkung ^entfernt wird:

grep -Po 'Logfile started :\K.*' process.log

Das Obige könnte auch von sedund Capture-Gruppen erreicht werden ()->\1:

sed -nr 's/^.*Logfile started :(.*)$/\1/p' process.log

Wo der Ausdruck ^.*<something>.*$mit der gesamten Zeile übereinstimmt, enthält das <something>. Der Befehl s/old/new/ersetzt diese Zeile durch den Inhalt der ersten Erfassungsgruppe (der Ausdruck in den Klammern könnte konkreter sein). Die Option -raktiviert die erweiterten regulären Ausdrücke. Die Option -nunterdrückt die normale Ausgabe von sedund schließlich pdruckt der Befehl die Übereinstimmungen.

pa4080
quelle
Ich hätte nie gedacht, awkdass es einen FS mit mehreren Zeichen mit Zeichen mit besonderer Bedeutung geben könnte! Was ich heute gelernt habe.
Floris
6

Da Sie dies bereits verarbeiten awk, können Sie das Ganze auch direkt ausführen:

$ echo "foo bar :29.06.2019 23:03:17" |  awk '{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

Das suballgemeine Format des Befehls ist sub(/REGEX/, REPLACEMENT, TARGET)und ersetzt alle Übereinstimmungen für den regulären Ausdruck REGEXdurch die Zeichenfolge REPLACEMENTin der Eingabezeichenfolge TARGET. Hier ersetzen wir das erste :( ^bedeutet "den Anfang") aus dem dritten Feld ( $3) durch nichts.

Wenn Sie das in awk tun, können Sie natürlich auch alles in awk tun und das Ganze in einer einzigen Operation erledigen:

$ echo "Logfile started :29.06.2019 23:03:17" | 
    awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

Oder in Ihrem Fall:

TDS="$(awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' process.log)"
echo "$TDS"
Terdon
quelle
0

Eine andere Bash-Lösung:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • Dies verwendet die Pipeline anstelle der Zwischenvariablenzuweisung.
  • Der Befehl xargskonvertiert stdin(Standardeingabe) in Positionsparameter für den bashBefehl.
  • Ersetzen echodurch tail -n1 /path/to/reportfile.txt.
WinEunuuchs2Unix
quelle