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 quesedtambié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' nomidebería hacerRespuestas:
Si está utilizando GNU
sed, intente:sedno 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
awkLos rangos en el
awktrabajo 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.
1La abreviatura críptica de este awk para imprimir la línea.
fuente
sedembargo, eso supone GNU .awk '!r && /claudio/ {sub(/claudio/,"claudia"); r=1} 1'awk !x{x=sub(/claudio/,"claudia")}10,/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
sedadmite la-zopción.Puede usar esta opción cuando desee
sedtrabajar en diferentes líneas.devoluciones
fuente
Puede usar
awkuna 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
:xybx. 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 siclaudioestá 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
claudioen 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