Con el estándar sed, nunca verá una nueva línea en el texto leído de un archivo. Esto se debe a que sedlee línea por línea y, por lo tanto, no hay una nueva línea al final del texto de la línea actual en sedel espacio del patrón. En otras palabras, sedlee datos delimitados por nueva línea, y los delimitadores no son parte de lo que sedve un script.
Las expresiones regulares se pueden anclar al final de la línea usando $(o al principio, usando ^). Anclar una expresión al inicio / final de una línea la obliga a coincidir exactamente allí, y no en cualquier lugar de la línea.
Si desea reemplazar cualquier cosa que coincida con el patrón [A-Za-z]*al final de la línea con algo, entonces ancle el patrón de esta manera:
[A-Za-z]*$
... lo obligará a coincidir al final de la línea y en ningún otro lugar.
Sin embargo, dado que [A-Za-z]*$tampoco coincide con nada (por ejemplo, la cadena vacía presente al final de cada línea), debe forzar la coincidencia de algo , por ejemplo, especificando
[A-Za-z][A-Za-z]*$
Entonces, su línea de comando sed será
$ sed 's/[A-Za-z][A-Za-z]*$/replace/' file.txt
No utilicé el -Einterruptor aquí porque no es necesario. Con eso, podrías haber escrito
Aunque sabía cómo hacerlo, obtendrás un +1 solo por usar el término técnico para ello. :) Entonces esto se llama anclaje - es bueno saberlo. Hasta ahora, siempre tuve que parafrasearlo ... Otra nota sobre+ : PUEDES usarlo incluso sin usar expresiones regulares extendidas, solo recuerda escribirlo como \+. Así sed -e 's/[A-Za-z]\+$/replace/' file.txtfuncionará perfectamente incluso sin GNU sedinstalado. Y no se debe olvidar: no lo use -E, ya que GNU sedno lo admite .
syntaxerror
1
@syntaxerror: creo que puede eliminar la última oración o al menos desmarcarla como gnu seddefinitivamente lo admite-E .
don_crissti
@don_crissti Bueno, pensé que has estado en esta red el tiempo suficiente para saber que no hay forma de deshacer partes de un comentario (a menos que lo reescribas por completo). Así que permítanme corregir: GNU sedpuede admitir "silenciosamente" -E, pero no está documentado en la página de manual (ni en el manual de Texinfo (revisado ambos)). Por lo tanto, supuse que no es compatible (que era una suposición incorrecta, después de todo). De todos modos, tienes razón, porque al menos GNU sedno se quejará si usas esta opción.
syntaxerror
@don_crissti Me alegro de haberlo hecho! Así, al menos, se ha confirmado que sedva a tomar una opción en particular que no ha sido adecuadamente documentado aún. Esto siempre es útil; Si nadie está al tanto de la falta de documentación, nadie lo solucionará.
syntaxerror
@syntaxerror, consulte unix.stackexchange.com/a/310454/135943 . Por supuesto, si tiene que trabajar con sistemas antiguos como RHEL 5, entonces usará una versión de GNU sed que no es compatible -E.
Comodín el
3
sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt
O bien, la forma compleja larga e innecesaria:
He descubierto que esto se puede hacer, todavía usando sed, con la ayuda de tr. Puede asignar otro carácter para representar el final de la línea. Se debe usar otro carácter temporal, en este caso "` ". Usemos "~" para representar el final de la línea:
No estoy seguro de entender ... ¿Por qué no anclas al final de la línea $? por ejemplos/[a-zA-Z]*$/replace/
don_crissti
1
2 puntos: 1) Es mejor usarlo en \+lugar de hacerlo, *ya que este último permite cero letras al final de la cadena; 2) Puedes usar una clase de personaje [[:alpha:]]. Entonces:sed 's/[[:alpha:]]\+$/replace/' file
Glenn Jackman
@glennjackman ¿Cuál es la barra diagonal inversa antes del plus? ¿No coincidiría con el carácter de suma?
Por el fragmento de código (roto) que publicó, parece que también desea reemplazar la nueva línea. En ese caso, el anclaje de expresiones regulares por sí solo no puede ayudarte. La siguiente es una solución:
sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file
Desglosado:
/[a-zA-Z]\+$/{} significa aplicar lo que viene dentro de los curvas a las líneas que coinciden con la expresión regular.
Dentro de los curlies, Nsignifica "agregar la siguiente línea al búfer activo" (lo que sedllama el "espacio del patrón")
Finalmente, la s///declaración es su sustitución requerida. Ahora funciona porque el espacio del patrón contiene dos líneas sucesivas y, por lo tanto, la nueva línea forma parte de ella.
+
: PUEDES usarlo incluso sin usar expresiones regulares extendidas, solo recuerda escribirlo como\+
. Asísed -e 's/[A-Za-z]\+$/replace/' file.txt
funcionará perfectamente incluso sin GNUsed
instalado. Y no se debe olvidar: no lo use-E
, ya que GNUsed
no lo admite .gnu sed
definitivamente lo admite-E
.sed
puede admitir "silenciosamente"-E
, pero no está documentado en la página de manual (ni en el manual de Texinfo (revisado ambos)). Por lo tanto, supuse que no es compatible (que era una suposición incorrecta, después de todo). De todos modos, tienes razón, porque al menos GNUsed
no se quejará si usas esta opción.sed
va a tomar una opción en particular que no ha sido adecuadamente documentado aún. Esto siempre es útil; Si nadie está al tanto de la falta de documentación, nadie lo solucionará.-E
.O bien, la forma compleja larga e innecesaria:
fuente
$
? por ejemplos/[a-zA-Z]*$/replace/
\+
lugar de hacerlo,*
ya que este último permite cero letras al final de la cadena; 2) Puedes usar una clase de personaje[[:alpha:]]
. Entonces:sed 's/[[:alpha:]]\+$/replace/' file
-r
opción utiliza esta sintaxis de expresión regular .Por el fragmento de código (roto) que publicó, parece que también desea reemplazar la nueva línea. En ese caso, el anclaje de expresiones regulares por sí solo no puede ayudarte. La siguiente es una solución:
Desglosado:
/[a-zA-Z]\+$/{}
significa aplicar lo que viene dentro de los curvas a las líneas que coinciden con la expresión regular.N
significa "agregar la siguiente línea al búfer activo" (lo quesed
llama el "espacio del patrón")s///
declaración es su sustitución requerida. Ahora funciona porque el espacio del patrón contiene dos líneas sucesivas y, por lo tanto, la nueva línea forma parte de ella.fuente
Para encontrar el final de la línea, solo use el signo $ :
Sin ancla de final de línea:
Sin ancla de final de línea:
fuente