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.