2009-09-21 11 views
25

Tengo un archivo con aproximadamente 1000 líneas. Todas las líneas comienzan con un número de siete dígitos, excepto por la línea ocasional. Necesito atrapar estas líneas y unirlas con la línea anterior.¿Cómo consigo que Vim coincida con una línea que no comienza con un número de siete dígitos?

He conseguido ser capaz de adaptarse a cualquier línea que comienza con un número de siete dígitos con el siguiente patrón de expresión:

^\d\{7} 

no puedo parecer conseguirlo para que coincida con cualquier línea que no coincide con aunque este patrón, que es realmente lo que estoy buscando.

Como una segunda pregunta que incluiré en esta. ¿Es posible tener alguna línea que coincida (o que no coincida para mantener la coherencia con lo que estoy tratando de hacer) para unirse a la línea anterior (en oposición al J que lleva la siguiente línea al el actual)?

Gracias

Respuesta

30
^\(\d\{7}\)\@! 

Ésta es la sintaxis de expresiones regulares de vim para una búsqueda negativa hacia delante.

Si usted está haciendo esto como una orden de masas :, usted debe ser capaz de simplemente hacer

:v/^\d\{7}/-1j 
+0

Por extraño que parezca, ambos resultan en lo mismo. Aunque para mí no tiene sentido que el que no tiene^realmente esté trabajando, no es que lo piense. –

+0

La única diferencia es que el que no tiene^coincidirá si hay un número de siete dígitos en algún lugar de la línea que no sea el comienzo. – chaos

+0

Ah, sí, ya veo. En este caso, no fue así, por lo que no se modificaron las líneas adicionales ... explica por qué el recuento de menos líneas fue exactamente el mismo. –

6

La expresión regular

^\(\d\{7}\)\@! 

va a invertir su expresión original. Para obtener más información acerca de la sintaxis, ver aquí:

:help \@! 

En cuanto al segundo problema, que podría, por ejemplo, reemplazar el salto de línea final en las líneas anteriores con nada:

:%s/$\n^\(\d\{7}\)\@!//g 
+0

Este estaba cerca, pero la combinación de la otra respuesta dejó un espacio entre las líneas que se unieron (que en realidad es lo que necesito). Este ejemplo coloca el último carácter de la primera línea directamente antes del primer carácter de la línea siguiente. Este es un efecto secundario que debo evitar. Aún así, +1 por su respuesta y gracias. –

+0

¡Oh bien! Sin embargo, el espacio se puede agregar así::% s/$ \ n^\\ (\ d \ {7} \\) \ @!// G – tobiasvl

+0

Cierto. El otro es más corto y soy flojo; P –

1

Aquí está mi solución utilizando awk, que se puede llamar dentro de vim:

$ cat seven.awk 
# Script to join lines that does not start with 7 digits 
/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ { print; next } 
{ printf $0; getline; print } 

$ cat seven.txt 
123 
4579 bad 
7654321 This line is OK 
1234567 OK So is this 
111 
2222 bad again 
4443333 OK again 

$ awk -f seven.awk seven.txt 
1234579 bad 
7654321 This line is OK 
1234567 OK So is this 
1112222 bad again 
4443333 OK again 

Por favor, disculpe mi expresión torpe: mi awk es viejo y no entiende la expresión de lujo como: \ d {7}. Si desea invocar este comando desde el interior de vim para todo el archivo:

:%!awk -f seven.awk 
+0

Originalmente también tuve [0-9] siete veces. Me alegré mucho de que el editor ex en gVim permitiera el atajo de \ d {7}. –

9

Ahora, para la verdadera respuesta

La expresión regular que coincide con cadenas que no comienzan con 7 dígitos es muy simple :

.{0,6}([^0-9].*)? 

Un equivalente de expresiones regulares más clásico sin {} sintaxis es realmente más fácil de leer: nos muestra visualmente lo que está pasando:

(|.|..|...|....|.....|......)([^0-9].*)? 

I.e. coinciden entre 0 y 6 caracteres, que pueden ser cualquier cosa, opcionalmente seguidos de un no-ajuste que, si ocurre, puede ir seguido de cero o más caracteres adicionales. Esto garantiza que si una cadena de caracteres de siete caracteres o más se corresponde, al menos uno de los primeros siete caracteres es un no ajuste.

Para traducir este juego de líneas en Vim, añadimos un poco de escape y el anclaje:

^.\{0,6\}\([^0-9].*\)\?$ 

Yo no "hacer" \d; es muy nuevo. :)

+0

Por cierto, tuve mis dedos cruzados cuando escribí esa última línea, y produjo esta confirmación el mismo mes: http://www.kylheku.com/cgit/txr/commit/?id=e63c7be49e144d2ed3967c28243109342e17dcaa – Kaz

Cuestiones relacionadas