¿Cómo eliminar el primer colon ':' de una marca de tiempo?


10

Soy nuevo en programación !!

¿Alguien puede ayudar a eliminar el :en la primera posición en una marca de tiempo::29.06.2019 23:03:17

Actualmente estoy tratando de hacerlo usando los comandos awk / cut como se muestra a continuación:

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


29.06.2019 23

¡Y la salida no es lo que quería! Quiero imprimirlo como 29.06.2019 23:03:17.

Respuestas:


14

Para cortar el primer carácter, también puedes usar cut -c:

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

11

Utilizar

cut -d: -f2-

en lugar de

cut -d: -f2

para obtener cualquier cosa desde el segundo campo hasta el final de la línea:

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

8

awkes una herramienta genial, y puedes resolver tareas muy complejas con ella. Pero para su pregunta, preferiría apegarme a las capacidades básicas de bash.

Para esta fácil eliminación de sustitución, haría lo siguiente:

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

esto imprimirá:

29.06.2019 23:03:17

Cuando estaba en su posición y comencé a aprender programación y bash, aprendí mucho de este Manual:

ABS - Guía avanzada de secuencias de comandos Bash

Puede encontrar más ejemplos e información interesante sobre su problema aquí , busque 'Eliminación de subcadenas'.


3
+1 esto! Dado que la pregunta está etiquetada como "bash", debe considerarse preferir las excelentes capacidades de bash (aunque a menudo bastante oscuras) para manipular cadenas que son mucho más rápidas que cargar herramientas externas.
rexkogitans

2
@rexkogitans ya que ya estamos llamando a grep o awk para analizar un archivo, bash no será más rápido. De hecho, cada vez que necesite analizar un archivo bash será lento. Todos los proyectiles son lentos y bash es más lento que la mayoría. Dicho esto, las capacidades de manipulación de cadenas del shell son de hecho el mejor enfoque, pero solo si ya tiene la entrada como variable.
terdon

8

Aquí hay una sedsolución:

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

Lo que sed 's/^://'está haciendo el comando es sustituir sel carácter de dos puntos :desde el comienzo ^de cada línea con la cadena vacía //.

Aquí hay una awksolución complicada , donde cambiamos el separador de campo a ^:, descrito anteriormente, y sacamos el segundo campo (de cada línea):

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

La tarea podría llevarse a cabo también con grep( explicación ), probablemente esta podría ser la solución más rápida para una gran cantidad de datos:

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

O procese el archivo directamente con el siguiente comando, donde ^se elimina la limitación :

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

Lo anterior también podría lograrse mediante sedgrupos de captura ()->\1:

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

Donde la expresión ^.*<something>.*$coincidirá con la línea completa, que contiene <something>. El comando s/old/new/sustituirá esta línea por el contenido del primer grupo de captura (la expresión entre paréntesis podría ser más concreta). La opción -rhabilita las expresiones regulares extendidas. La opción -nsuprimirá la salida normal de sedy finalmente el comando pimprimirá las coincidencias.


¡Nunca supe que awkpodría tener un FS de varios caracteres con caracteres con un significado especial! Cosa que aprendí hoy.
Floris

6

Como ya está procesando esto awk, también puede hacer todo directamente:

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

El subformato general del comando es sub(/REGEX/, REPLACEMENT, TARGET)y reemplazará todas las coincidencias para la expresión regular REGEXcon la cadena REPLACEMENTen la cadena de entrada TARGET. Aquí, estamos reemplazando el primero :( ^significa "el comienzo") del tercer campo ( $3) con nada.

Por supuesto, si está haciendo eso en awk, también puede hacer todo en awk y hacer todo en una sola operación:

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

O, en tu caso:

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

0

Otra solución bash:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • Esto utiliza la canalización en lugar de la asignación de variable intermedia.
  • El comando xargsconvierte stdin(entrada estándar) en parámetros posicionales para el bashcomando.
  • Reemplazar echocon tail -n1 /path/to/reportfile.txt.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.