Podemos usar cualquiera de sed
o awk
para resolver completamente el problema.
Con sed
:
$ sed 's/^.\./0&/' file.txt
Cuando &
ocurre en la parte de reemplazo del comando de sustitución ( s
), se expandirá a la parte de la línea de entrada que coincida con la parte del patrón del comando.
La expresión regular ^.\.
significa "hacer coincidir todas las líneas que comienzan con ( ^
) un carácter arbitrario ( .
) seguido de un punto literal ( \.
) ".
Si la línea es 1.02.2017 23:40:00
, el patrón coincidirá y 1.
sería reemplazado por 01.
al comienzo de la línea.
Con awk
:
Sobre la base del awk
código parcial en la pregunta ...
Esto, como se indicó, imprimirá el segundo carácter de cada línea de entrada:
$ awk '{ print substr($0, 2, 1) }' file.txt
Podemos usar el hecho de que substr($0, 2, 1)
devuelve el segundo carácter y usarlo como condición:
$ awk 'substr($0, 2, 1) == "." { ... }' file.txt
Lo que entra { ... }
es un código que precede $0
, que es el contenido de la línea actual, con un cero si la condición anterior es verdadera:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt
Entonces solo necesitamos asegurarnos de que todas las líneas estén impresas:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt
La condición substr($0, 2, 1) == "."
, por supuesto, también puede cambiarse a una expresión regular (usamos exactamente la misma expresión que usamos en la sed
solución):
$ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt
Algunas personas que piensan que "más corto siempre es mejor" escribirían eso como
$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt
(y probablemente también eliminar la mayoría de espacios: awk '/^.\./{$0="0"$0}1' file.txt
)
sed 's/^.\./0&/' file.txt
. Creo que deberías poner eso al comienzo de esta respuesta. Aún así, +1.Con sed:
El patrón
/^.\./
busca cualquier carácter y un punto literal al comienzo de la línea^
, y si eso coincide,s
sustituya ese inicio de línea con un cero, agregando efectivamente el cero al comienzo.El sed expresoin
s/.\{0\}/0/
es algo extraño, coincide con cero o más copias de cualquier cosa y lo reemplaza por un cero. El patrón, por supuesto, coincidirá en todas las posiciones de la cadena, pero comos///
solo reemplaza la primera coincidencia, funciona como se esperaba. Sin embargo, es una forma pintoresca de hacerlo.O con awk, una expresión regular similar funcionaría para coincidir con la línea, pero podemos usar
substr
:Primero probamos si el segundo carácter es un punto, luego agregamos un cero al frente de la línea si es así. El último invoca la acción predeterminada de imprimir la línea después de cualquier modificación.
fuente
Dijiste awk y sed, pero parece que estás tratando de formatear una fecha y para eso usaría el
date
comando. Por ejemplo:saldrá
El
sed
comando en el medio cambia los puntos a barras para la entradadate -d
. Las opciones de formato permiten la salida en casi cualquier formato que desee. En%m
particular, hará cero el mes, que es lo que parece que estás tratando de hacer.Como Kusalananda señala:
Aún más compacto (fecha GNU y Bash):
date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
fuente
date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
s|\.|/|g
. De lo contrario, como se señaló anteriormente: Buena captura, +1Una estrategia diferente a la presentada en las otras respuestas: podría usar "." como el separador de campo.
Podrías jugar golf para:
Para sed, hay un comando más corto, presentado en otra respuesta (excelente).
fuente
awk -F. '{print ($1<10?0$0:$0)}' file
Con sed podría ser
Esto se usará
^
para anclar al comienzo de la línea, luego capturará cualquier carácter individual en un grupo, seguido de un literal.
, y luego cualquier otra cosa. Si coincidimos con que imprimimos un0
, entonces nuestro primer grupo de captura (el personaje al comienzo de la línea), luego un.
segundo grupo de captura (el resto de la línea)fuente
&
es tu amigo. Ver el ejemplo sed de Kusalananda.sed
que podría ser útil en otras situaciones, no solo este problema específico