2010-01-03 5 views
5

Tengo un archivo de texto (más correctamente, un “ estilo alemán “ archivo CSV, coma decimal separada por punto y coma) que tiene una fecha y el valor de una medida en cada línea.
Hay tramos de valores defectuosos que deseo eliminar antes de seguir trabajando. Me gustaría almacenar estos recortes en algunos guiones para que mis correcciones estén documentadas y pueda reproducir esas correcciones si es necesario.Eliminar líneas que están entre patrones dados de un archivo (usando herramientas de Unix)

Las líneas de este aspecto:

28.01.2005 14:48:38;5,166 
28.01.2005 14:50:38;2,916 
28.01.2005 14:52:38;0,000 
28.01.2005 14:54:38;0,000 
(long stretch of values that should be removed; could also be something else beside 0) 
01.02.2005 00:11:43;0,000 
01.02.2005 00:13:43;1,333 
01.02.2005 00:15:43;3,250 

Ahora me gustaría para almacenar una lista de inicio y fin patrones como 28.01.2005 14:52:38 + 01.02.2005 00:11:43, y el guión habría cortado las líneas que coincidan con estos empiezan pares/finales y todo lo que está entre ellos.

Estoy pensando en hackear una secuencia de comandos awk, pero tal vez me falta una herramienta ya existente.

(líneas de impresión no coinciden)

Respuesta

16

Tenga una mirada en sed:

sed '/start_pat/,/end_pat/d' 

eliminará líneas entre start_pat y end_pat (inclusive).

Para eliminar varios de estos pares, puede combinarlos con múltiples opciones -e:

sed -e '/s1/,/e1/d' -e '/s2/,/e2/d' -e '/s3/,/e3/d' ... 
+0

¡Genial! Sabía que me estaba perdiendo algo & hellip; Siempre utilicé sed con patrones únicos y nunca recordé que ofrece rangos. –

+0

Además, puedo poner las expresiones en un archivo, donde también puedo usar comentarios (con '#'). La línea de comando es 'sed -f scriptfile outfile'. –

-1

uso grep -L

Lo sentimos - pensaban que sólo quería sin líneas 0000 al final

+0

grep -L imprimirá nombres de archivo no coincidentes. grep -v imprimiría líneas que no coinciden, pero el OP parece estar detrás de algo más complicado (usando rangos). – mopoke

+0

Ok, pensé que solo querían imprimir anyting sin 0.000 al final –

+0

De hecho, mi ejemplo fue un poco engañoso – hay otros valores defectuosos además de 0, p. negativos. –

0

En primer lugar, ¿por qué necesita para mantener un registro de lo que has hecho? ¿Por qué no mantener una copia de seguridad del archivo original, o tomar una diferencia entre los viejos archivos &, o ponerlo bajo control de fuente?

Para los cambios reales sugiero usar Vim.

El comando Vim :global (abreviado como :g) se puede utilizar para ejecutar: comandos ex en líneas que coinciden con una expresión regular. Esto es en muchos sentidos más poderoso que awk, ya que los comandos pueden referirse a rangos relativos a la línea coincidente, además de que tiene el poder de procesamiento de texto completo de Vim a su disposición.

Por ejemplo, esto va a hacer algo parecido a lo que quiere (no probado, caveat por lo salvedad):

:g!/^\d\d\.\d\d\.\d\d\d\d/ -1 write tmp.txt >> | delete 

Esto coincide con las líneas que no comienzan con una fecha (el ! niega el partido), APPENDs la línea anterior al archivo tmp.txt, luego borra la línea actual.

Probablemente terminará con líneas duplicadas en tmp.txt, pero se pueden eliminar ejecutando el archivo a través de uniq.

+0

Me gustaría mantener notas breves sobre los registros que arrojé y por qué. Trabajaré con estos datos con poca frecuencia, y sé que podría olvidar lo que hice. Además, alguien más puede necesitar comprender y reproducir lo que hice. Lamentablemente, su ejemplo vi/ex realmente no resuelve mi problema, porque todas las líneas comienzan con una fecha. Pero entiendo la dirección a la que apunta. –

0

también está awk utiliza

awk '/start/,/end/' file 
+1

En alguna parte se mencionó que awk es apropiado cuando los datos se representan en formato de columna. Es eso correcto. ¿Podría explicar por favor si awk es mejor que sed por ** esta ** tarea particular? –

0

Yo sugeriría seriamente el aprendizaje de los conceptos básicos de Perl (es decir, no las cosas OO). Te pagará en cargas de cubeta.

Escribir un poco de perl para hacer esto (y muchas otras tareas) es rápido y sencillo una vez que haya comprendido los fundamentos, que si está acostumbrado a usar awk, sed, grep, etc., son bastante simples.

No tendrá que recordar cómo usar muchas herramientas diferentes y donde anteriormente habría utilizado múltiples herramientas interconectadas para resolver un problema, solo puede usar una sola secuencia de perl (generalmente mucho más rápida de ejecutar).

Y, Perl está instalado en prácticamente todas las distribuciones de Unix/Linux ahora.

(that sed está ordenado aunque :-)

Cuestiones relacionadas