Archivo original
claudio
antonio
claudio
michele
Quiero cambiar solo la primera aparición de "claudio" con "claudia" para que el resultado del archivo
claudia
antonio
claudio
michele
Yo he tratado
sed -e '1,/claudio/s/claudio/claudia/' nomi
Pero realice una sustitución global. ¿Por qué?
info sed
: (0,/REGEXP/
: Se puede usar un número de línea de 0 en una especificación de dirección como0,/REGEXP/
para quesed
también intente hacer coincidir REGEXP en la primera línea de entrada. En otras palabras,0,/REGEXP/
es similar a1,/REGEXP/
, excepto que si ADDR2 coincide con la primera línea de entrada, el formulario 0, / REGEXP / considerará que finaliza el rango, mientras que el formulario 1, / REGEXP / coincidirá con el comienzo de su rango y, por lo tanto, hará que el rango abarque hasta la segunda aparición de la expresión regular)awk '/claudio/ && !ok { sub(/claudio/,"claudia"); ok=1 } 1' nomi
debería hacerRespuestas:
Si está utilizando GNU
sed
, intente:sed
no comienza a verificar la expresión regular que termina un rango hasta después de la línea que comienza ese rango.De
man sed
(página de manual de POSIX, énfasis mío):Utilizando
awk
Los rangos en el
awk
trabajo son más esperados:Explicación:
NR==1,/claudio/
Este es un rango que comienza con la línea 1 y termina con la primera aparición de
claudio
.sub(/claudio/, "claudia")
Mientras estamos en el rango, se ejecuta este comando sustituto.
1
La abreviatura críptica de este awk para imprimir la línea.
fuente
sed
embargo, eso supone GNU .awk '!r && /claudio/ {sub(/claudio/,"claudia"); r=1} 1'
awk !x{x=sub(/claudio/,"claudia")}1
0,/claudio/
Aquí hay 2 esfuerzos programáticos más con sed: ambos leen todo el archivo en una sola cadena, luego la búsqueda solo reemplazará al primero.
Con comentario:
fuente
Una nueva versión de GNU
sed
admite la-z
opción.Puede usar esta opción cuando desee
sed
trabajar en diferentes líneas.devoluciones
fuente
Puede usar
awk
una bandera para saber si el reemplazo ya se realizó. Si no, proceda:fuente
En realidad, es realmente fácil si solo configura un pequeño retraso: no hay necesidad de buscar extensiones poco confiables:
Eso solo difiere la primera línea a la segunda y la segunda a la tercera y etc.
Imprime:
fuente
Y una opción más
La ventaja es que usa comillas dobles, por lo que puede usar variables dentro, es decir.
fuente
Esto también se puede hacer sin el espacio de espera y sin concatenar todas las líneas en el espacio del patrón:
Explicación: Intentamos encontrar "claudio" y si lo hacemos saltamos al pequeño ciclo print-load-loop entre
:x
ybx
. De lo contrario, imprimimos y reiniciamos el script con la siguiente línea.fuente
fuente
Resumen
Sintaxis de GNU:
O incluso (para usar solo una vez la palabra a reemplazar:
O, en la sintaxis POSIX:
funciona en cualquier sed, procesa solo tantas líneas como sea necesario para encontrar el primero
claudio
, funciona incluso siclaudio
está en la primera línea y es más corto ya que usa solo una cadena de expresiones regulares.Detalle
Para cambiar solo una línea , debe seleccionar solo una línea.
Usando un
1,/claudio/
(de su pregunta) selecciona:claudio
.Para seleccionar cualquier línea que contenga
claudio
, use:Y para seleccionar solo el primero
claudio
en el archivo, use:Luego, puede hacer una sustitución solo en esa línea:
Lo que cambiará solo la primera aparición de la coincidencia de expresiones regulares en la línea, incluso si puede haber más de una, en la primera línea que coincida con la expresión regular.
Por supuesto, la
/claudio/
expresión regular podría simplificarse para:Y, entonces, lo único que falta es imprimir todas las demás líneas sin modificar:
fuente