¿Cómo insertar una nueva línea antes de un patrón dentro de una línea?
Por ejemplo, esto insertará una nueva línea detrás del patrón regex.
sed 's/regex/&\n/g'
¿Cómo puedo hacer lo mismo pero delante del patrón?
Dado este archivo de entrada de muestra, el patrón para coincidir es el número de teléfono.
some text (012)345-6789
Debe convertirse
some text
(012)345-6789
sed '/regex/G'
Respuestas:
Esto funciona
bash
yzsh
, probado en Linux y OS X:En general, para
$
seguido de un literal de cadena entre comillas simples, sebash
realiza una sustitución de barra diagonal inversa de estilo C, por ejemplo,$'\t'
se traduce a una pestaña literal. Además, sed quiere que su literal de nueva línea se escape con una barra diagonal inversa, de ahí lo\
anterior$
. Y, por último, el signo de dólar en sí no debe citarse para que sea interpretado por el shell, por lo tanto, cerramos la cotización antes del$
y luego la abrimos nuevamente.Editar : como se sugiere en los comentarios de @ mklement0, esto también funciona:
Lo que sucede aquí es: todo el comando sed ahora es una cadena de estilo C, lo que significa que la barra invertida que sed requiere que se coloque antes de que la nueva línea literal se escape con otra barra invertida. Aunque es más legible, en este caso no podrá realizar sustituciones de cadenas de shell (sin volver a hacerlo feo).
fuente
sed '\(first match\)\(second match\)/\1\'$'\n''\2/g'
. Tenga en cuenta las dos comillas simples después de \ n. La primera cierra la$
sección " " para que el resto de la línea no se vea afectada por ella. Sin esas citas, el \ 2 fue ignorado.sed $'s/regexp/\\\n/g'
que mejora la legibilidad; la única advertencia es que luego debe duplicar todos los\
caracteres literales .Algunas de las otras respuestas no funcionaron para mi versión de sed. Cambiando la posición de
&
y\n
funcionó.Editar: Esto no parece funcionar en OS X, a menos que lo instale
gnu-sed
.fuente
brew install gnu-sed
seguido degsed 's/regexp/\n&/g'
echo 'alias sed=gsed' >> ~/.bashrc
En sed, no puede agregar nuevas líneas en la secuencia de salida fácilmente. Necesita usar una línea de continuación, que es incómoda, pero funciona:
Ejemplo:
Ver aquí para más detalles. Si quieres algo un poco menos incómodo, puedes intentar usarlo
perl -pe
con grupos de coincidencias en lugar de sed:$1
se refiere al primer grupo coincidente en la expresión regular, donde los grupos están entre paréntesis.fuente
perl -pi -e 's/(.*)/\n$1/' foo
s
llamada de función (a diferencia de la implementación Sed de GNU , que sí lo hace) . La respuesta anterior funciona con ambas implementaciones; Para obtener una descripción general de todas las diferencias, consulte aquí .En mi Mac, lo siguiente inserta una 'n' en lugar de una nueva línea:
Esto reemplaza con nueva línea:
fuente
sed -i '' -e ...
y estaba teniendo problemas con una^M
letra M (ctrl + m) escrita en el archivo. Terminé usando perl con los mismos parámetros.\n
).echo...
nueva línea) que acabo de hacer esto en vim.sed "s/regexp/`echo`/g"
- esto producirá un solo LF en lugar de LF-CR`echo`
dará como resultado una cadena vacía , porque las sustituciones de comandos invariablemente recortan todas las nuevas líneas finales. No hay forma de usar una sustitución de comando para insertar directamente una nueva línea nueva (y la inserción\n\r
, es decir, un CR adicional, es una idea terrible).fuente
$'\n'
depende del shell para generar la nueva línea. Dichas soluciones pueden no ser portátiles. Este es. Por supuesto, también es un duplicado del segundo ejemplo en la respuesta de tgamblin de 2009.En este caso, no uso sed. Yo uso tr.
Esto toma la coma y la reemplaza con el retorno de carro.
fuente
cat Somefile | tr ',' '\n'
YMMVPuede usar perl one-liners como lo hace con sed, con la ventaja de una expresión regular perl completa soporte (que es mucho más poderoso que lo que obtiene con sed). También hay muy poca variación en las plataformas * nix: perl es generalmente perl. Por lo tanto, puede dejar de preocuparse por cómo hacer que la versión particular de sed de su sistema haga lo que desea.
En este caso, puedes hacer
-pe
pone a Perl en un bucle de "ejecutar e imprimir", muy parecido al modo de operación normal de sed.'
cita todo lo demás para que el caparazón no interfiera()
Alrededor de la expresión regular hay un operador de agrupación.$1
en el lado derecho de la sustitución imprime lo que coincida dentro de estos parens.Finalmente,
\n
es una nueva línea.Independientemente de si está utilizando paréntesis como operador de agrupación, debe escapar de cualquier paréntesis que intente hacer coincidir. Entonces, una expresión regular para que coincida con el patrón que enumeras arriba sería algo así como
\(
o\)
coincide con un par literal, y\d
coincide con un dígito.Mejor:
Me imagino que puedes descubrir qué están haciendo los números entre llaves.
Además, puede usar delimitadores que no sean / para su expresión regular. Entonces, si necesitas unir / no tendrás que escapar. Cualquiera de los siguientes es equivalente a la expresión regular al comienzo de mi respuesta. En teoría, puede sustituir cualquier carácter por el estándar / 's.
Un par de pensamientos finales.
usar en
-ne
lugar de-pe
actuar de manera similar, pero no se imprime automáticamente al final. Puede ser útil si desea imprimir por su cuenta. Por ejemplo, aquí hay un grep-like (m/foobar/
es una coincidencia de expresiones regulares):Si le resulta problemático lidiar con las nuevas líneas y desea que se maneje mágicamente por usted, agregue
-l
. Sin embargo, no fue útil para el OP, que estaba trabajando con nuevas líneas.Sugerencia adicional: si tiene instalado el paquete pcre, viene con él
pcregrep
, que utiliza expresiones regulares compatibles con perl.fuente
Hmm, las líneas nuevas escapadas parecen funcionar en versiones más recientes de
sed
(Tengo GNU sed 4.2.1),fuente
funcionó bien en El Captitán con
()
apoyofuente
Para insertar una nueva línea para transmitir en Linux, utilicé:
Donde
file1
estaba:Antes del reemplazo de sed in situ, y:
Después del reemplazo de sed en el lugar. Tenga en cuenta el uso de
\\\n
. Si los patrones tienen un"
interior, escapa usando\"
.fuente
sed
inserta en\n
lugar de LF porque ingresa\\n
el parámetro desde el shell. --- Este código funciona:sed -i "s/def/abc\ndef/" file1
. ---GNU sed version 4.2.1
,GNU bash, version 4.1.2(1) / 4.2.25(1)
(CentOS versión 6.4 / Ubuntu 12.04.3).en sed puede hacer referencia a grupos en su patrón con "\ 1", "\ 2", ... así que si el patrón que está buscando es "PATRÓN", y desea insertar "ANTES" delante de él , puedes usar, sin escapar
es decir
fuente
También puede hacer esto con awk, usando
-v
para proporcionar el patrón:Esto verifica si una línea contiene un patrón dado. Si es así, agrega una nueva línea al comienzo.
Vea un ejemplo básico:
Tenga en cuenta que afectará a todos los patrones en una línea:
fuente
1
se usa en Awk como una abreviatura de{print $0}
. La razón es que cualquier condición que se evalúe como Verdadero desencadena la acción predeterminada de Awk, que consiste en imprimir el registro actual.Esto funciona en MAC para mí
Dono si es perfecto ...
fuente
Después de leer todas las respuestas a esta pregunta, todavía me llevó muchos intentos obtener la sintaxis correcta para el siguiente script de ejemplo:
El script agrega una nueva línea
\n
seguida de otra línea de texto al final de un archivo usando un solosed
comando.fuente
\ 0 es nulo, por lo que su expresión se reemplaza por nulo (nada) y luego ...
\ n es la nueva línea
En algunos sabores de Unix no funciona, pero creo que es la solución a su problema.
fuente
En vi en Red Hat, pude insertar retornos de carro usando solo el carácter \ r. Creo que esto ejecuta internamente 'ex' en lugar de 'sed', pero es similar, y vi puede ser otra forma de hacer ediciones masivas, como parches de código. Por ejemplo. Estoy rodeando un término de búsqueda con una declaración if que insiste en retornos de carro después de las llaves:
Tenga en cuenta que también tuve que insertar algunas pestañas para que las cosas se alineen mejor.
fuente