Tengo un archivo que tiene un montón de nombres de host correlacionados con IP que se ve así:
x-cluster-front-1 192.168.1.2
x-cluster-front-2 192.158.1.10
y-cluster-back-1 10.1.11.99
y-cluster-back-2 10.1.157.38
int.test.example.com 59.2.86.3
super.awesome.machine 123.234.15.6
Quiero que se vea así:
x-cluster-front-1 192.168.1.2
x-cluster-front-2 192.158.1.10
y-cluster-back-1 10.1.11.99
y-cluster-back-2 10.1.157.38
int-test-example-com 59.2.86.3
super-awesome-machine 123.234.15.6
¿Cómo puedo reemplazar el. (puntos) de la primera columna con - (guión) para facilitar una ordenación por la segunda columna? Estaba pensando en usar sed para reemplazar los puntos hasta el primer espacio, o reemplazar cada punto excepto los últimos tres, pero tengo problemas para entender regex y sed. ¡Puedo realizar reemplazos simples pero esto está muy por encima de mi cabeza!
Esto es parte de un script más grande que he estado escribiendo en bash. Estoy atrapado en esta parte.
awk
se basa ennawk
, por lo que todas lasawk
implementaciones modernas deberían tenergsub
. En Solaris, puede necesitar/usr/xpg4/bin/awk
onawk
.Si necesita hacer las sustituciones en el primer campo, lo mejor es usar la solución awk de Rahul, pero tenga en cuenta que puede afectar el espacio (los campos se reescriben con un solo espacio entre ellos).
Puede evitarlo escribiéndolo en su lugar:
La
-p
bandera significa "leer el archivo de entrada línea por línea e imprimir cada línea después de aplicar el script dado por-e
". Entonces, el sustituto de (s|pattern|replacement|
) la primera secuencia de caracteres no espaciales (\S+
) con el patrón emparejado ($&
) después de sustituir todo.
con-
. El truco es usars|||e
donde ele
operador evaluará una expresión como reemplazo. Por lo tanto, puede tener un reemplazo (tr/./-/
) aplicado a la coincidencia ($&
) del anterior (s|||e
).Si necesita sustituir cada uno
.
con un-
excepto los últimos 3 últimos, con GNUsed
y suponiendo que tiene unrev
comando:fuente
/r
que funcione).Sed no es la herramienta más fácil para el trabajo; vea otras respuestas para obtener mejores herramientas, pero se puede hacer.
Para reemplazar
.
por-
sólo hasta el primer espacio, el usos
en un bucle.(Tenga en cuenta que algunas implementaciones de sed no admiten comentarios en la misma línea. GNU sed sí lo hace).
Para realizar el reemplazo hasta el último espacio:
Otra técnica hace uso del espacio de retención de sed. Guarde el bit que no desea modificar en el espacio de espera, haga su trabajo, luego recupere el espacio de espera. Aquí, divido la línea en el último espacio y reemplazo los puntos por guiones en la primera parte.
fuente
Dado que Rahul le dio la respuesta canónica para su caso de uso, pensé en intentar responder al problema titular: sustituir todas las ocurrencias x, excepto las últimas, de una expresión regular:
El código anterior (probado) no supone que tenga campos separados por espacios. Reemplazará todos los puntos en una línea con guiones, excepto los últimos 3 puntos. Reemplace el
3
en el código a su gusto.fuente
Puede usar muchas herramientas diferentes para esto. Rahul Patil ya te dio
gawk
uno, así que aquí hay algunos otros:perl
El
-a
interruptor hace que Perl divida automáticamente las líneas de entrada en el espacio en blanco y guarde los campos resultantes en la matriz@F
. El primer campo, por lo tanto, será$F[0]
así que reemplazamos (s///
) todas las apariciones de.
with-
en el primer campo y luego imprimimos toda la matriz.cáscara
Aquí, el bucle while lee el archivo y se divide automáticamente en espacios en blanco. Esto crea dos campos
$first
y$rest
. La construcción${first//pattern/replacement}
reemplaza todas las ocurrencias depattern
conreplacement
.fuente
perlrun(1)
le diré que-a
es "modo de división automática", prefiero pensar en él como "awk
modo": DCreo que esto es un poco más fácil de leer que una gran expresión regular desagradable. Básicamente, simplemente dividí la línea en dos campos en el espacio en blanco y utilicé sed en la primera parte.
Dependiendo de su shell, también podría usar $ {host //./-} en lugar del comando sed.
fuente
Sin usar
g
al final del comando puede hacer esto ... Esto simplemente reemplazará la primera aparición del patrónfuente