Tengo problemas para reducir mi sintaxis sed para agregar un número variable de ceros a un esquema organizativo numérico. Las cadenas en las que estoy operando aparecen como
1.1.1.1,Some Text Here
aprovechando la sintaxis sed
sed -r ":r;s/\b[0-9]{1,$((1))}\b/0&/g;tr"
Soy capaz de obtener la respuesta
01.01.01.01,Some Text Here
Sin embargo, lo que estoy buscando es algo para rellenar con ceros hasta 2 dígitos en los campos 2 y 3 y 3 dígitos en el campo 4 para que todos los elementos tengan una longitud estándar en [0-9]. [0-9] { 2}. [0-9] {2}. [0-9] {3}
1.01.01.001,Some Text Here
Por mi vida, ni siquiera puedo imaginar cómo modificar el límite para incluir los parámetros necesarios para ajustar solo a los números después de un período. Creo que tiene algo que ver con el uso de la \ b que entiendo coincide con cero caracteres en un límite de palabra, pero no entiendo por qué mis intentos de agregar un punto a la coincidencia fallan de la siguiente manera:
sed -r ":r;s/\.\b[0-9]{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b\.[0-9]{1,$((1))}\b/0&/g;tr"
Both cause the statement to hang
sed -r ":r;s/\b[0-9]\.{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\.\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\b\./0&/g;tr"
cause the statement to output:
1.01.01.1,Some Text Here
Además, espero tener problemas adicionales si la declaración contiene texto como:
1.1.1.1,Some Number 1 Here
Es una conclusión inevitable que necesito aprender realmente sed y todas sus complejidades. Estoy trabajando en eso, pero espero que esta declaración en particular continúe causándome problemas por un tiempo. Cualquier ayuda sería muy apreciada.
EDITAR: He descubierto una forma ... Esta declaración parece hacer lo que estoy buscando, pero debe haber una forma más elegante de hacerlo.
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
Además, sintácticamente, esto causará problemas si aparece un formato de número similar en el texto ... similar a:
1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3
En cuyo caso resultará en:
1.01.01.001,Some Text Referring to Document XXX Heading 01.02.03
Resuelto Gracias a todos por su ayuda aquí. Inicialmente resolví el problema con la respuesta que acepté a continuación. Tengo la sensación de haber movido la solución a Python como parte de una solución más grande que aprovecha el siguiente tipo:
def getPaddedKey(line):
keyparts = line[0].split(".")
keyparts = map(lambda x: x.rjust(5, '0'), keyparts)
return '.'.join(keyparts)
s=sorted(reader, key=getPaddedKey)
fuente
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
Sin embargo, me encantaría saber si hay un enfoque más elegante.printf
(o unaprintf
llamada dentro de Awk) puede ser más sencillo.Respuestas:
Uso:
leading_zero.sh input.txt
Explicación:
input.txt
output.txt
fuente
perl
versión no elimina las barras invertidas.bash puede manejar esto. Sin embargo, será mucho más lento que Perl:
fuente
printf
, la herramienta sensata. (Awkprintf
también tiene y está mejor diseñado quebash
para el procesamiento de texto). Consulte también ¿Por qué usar un bucle de shell para procesar texto se considera una mala práctica?No ha pedido específicamente una
perl
solución, pero aquí hay una de todos modos. Personalmente, creo que esto es un poco más fácil de leer, especialmente cuando se divide en varias líneas.Primero aquí está el one-liner:
Sus resultados:
Y aquí está el
perl
script desglosado y comentado (la-n
bandera pone unwhile read; do ... done
bucle implícito alrededor del código):fuente
awk
también funcionaría - mismo principio usandoprintf
Aquí hay un posible enfoque:
sed -E 's/([0-9]*\.)/0\1/g;s/.//;s/([0-9]*,)/00\1/'
Ejemplos
También trabaje con esta cadena:
... y esta cadena:
fuente
Explicación:
El método utilizado aquí es observar los vecindarios de los números y tomar medidas basadas en eso. Entonces, el segundo y tercer números ven un punto en ambos lados, mientras que el cuarto número ve un punto a la izquierda y una coma a la derecha.
El $ 1 se establece cuando la expresión regular toma el camino del segundo o tercer nums y, en consecuencia, el relleno de precisión es 2. OTOH, para el cuarto número, el relleno es 3.
% cat file.txt
Resultados:
fuente