Come rimuovere i primi due punti ":" da un timestamp?


10

Sono nuovo nella programmazione !!

Qualcuno può aiutare a rimuovere il :nella prima posizione in un timestamp::29.06.2019 23:03:17

Attualmente sto provando a farlo usando i comandi awk / cut come mostrato di seguito:

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


29.06.2019 23

E l'output non è quello che volevo! Voglio stamparlo come 29.06.2019 23:03:17.

Risposte:


14

Per tagliare il primo personaggio, puoi anche usare cut -c:

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

11

Uso

cut -d: -f2-

invece di

cut -d: -f2

per ottenere qualsiasi cosa dal secondo campo alla fine della riga:

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

8

awkè uno strumento interessante e puoi risolvere compiti molto complessi con esso. Ma per la tua domanda preferirei attenermi alle capacità di base di bash.

Per questa facile rimozione delle sottostazioni, farei quanto segue:

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

questo stamperà:

29.06.2019 23:03:17

Quando ero nella tua posizione e ho iniziato a studiare programmazione e bash, ho imparato molto da questo manuale:

ABS - Guida avanzata agli script di Bash

Alcuni altri esempi e informazioni interessanti sul tuo problema sono disponibili qui , cerca "Rimozione sottostringa".


3
+1 questo! Dato che la domanda è taggata "bash", dovrebbe essere considerata la preferenza per le grandi capacità (sebbene spesso piuttosto oscure) di bash di manipolare stringhe che sono molto più veloci del caricamento di strumenti esterni.
rexkogitans,

2
@rexkogitans poiché stiamo già chiamando grep o awk per analizzare un file, bash non sarà più veloce. In effetti, ogni volta che devi analizzare un file bash sarà lento. Tutte le shell sono lente e bash è più lento della maggior parte. Detto questo, le capacità di manipolazione delle stringhe della shell sono spesso l'approccio migliore, ma solo se hai già l'input come variabile.
terdon,

8

Ecco una sedsoluzione:

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

Ciò che il comando sed 's/^://'sta facendo è sostituire sil carattere di due punti :dall'inizio ^di ogni riga con la stringa vuota //.

Ecco una awksoluzione complicata , in cui cambiamo il separatore di campo in ^:, descritto sopra, e produciamo il secondo campo (di ogni riga):

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

L'attività potrebbe essere eseguita anche con grep( spiegazione ), probabilmente questa potrebbe essere la soluzione più veloce per una grande quantità di dati:

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

Oppure elabora il file direttamente con il comando seguente, dove ^viene rimossa la limitazione :

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

Quanto sopra potrebbe essere realizzato anche da sede catturare gruppi ()->\1:

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

Dove l'espressione ^.*<something>.*$corrisponderà all'intera riga, che contiene <something>. Il comando s/old/new/sostituirà questa riga con il contenuto del primo gruppo di acquisizione (l'espressione tra parentesi potrebbe essere più concreta). L'opzione -rabilita le espressioni regolari estese. L'opzione -neliminerà l'output normale di sede infine il comando pstamperà le corrispondenze.


Non avrei mai saputo che awkpotesse avere una FS multi-personaggio con personaggi con un significato speciale! Cosa che ho imparato oggi.
Floris,

6

Dato che lo stai già elaborando awk, puoi anche fare direttamente tutto:

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

Il subformato generale del comando è sub(/REGEX/, REPLACEMENT, TARGET)e sostituirà tutte le corrispondenze per l'espressione regolare REGEXcon la stringa REPLACEMENTnella stringa di input TARGET. Qui, stiamo sostituendo il primo :( ^significa "l'inizio") dal terzo campo ( $3) con niente.

Naturalmente, se lo stai facendo in awk, puoi anche fare tutto in awk e fare tutto in una sola operazione:

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

Oppure, nel tuo caso:

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

0

Un'altra soluzione bash:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • Questo utilizza la pipeline anziché l'assegnazione di variabili intermedie.
  • Il comando xargsconverte stdin(input standard) in parametri posizionali per il bashcomando.
  • Sostituisci echocon tail -n1 /path/to/reportfile.txt.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.