2012-03-27 12 views
22

Considere un archivo de texto con los datos científicos, por ejemplo .:¿Cómo puedo eliminar cada línea X en un archivo de texto?

5.787037037037037063e-02 2.048402977658663748e-01 
1.157407407407407413e-01 4.021264347118673754e-01 
1.736111111111111049e-01 5.782032163406526371e-01 

¿Cómo puedo eliminar fácilmente, por ejemplo, cada segunda línea, o cada 9 de cada 10 líneas en el archivo? ¿Es posible, por ejemplo, con un script bash?

Antecedentes: el archivo es muy grande pero necesito mucha menos información para trazar. Tenga en cuenta que estoy usando Ubuntu/Linux.

+0

¿Seguro que deseas apuntar-muestrear los datos de este tipo? Puede ser mejor hacer un muestreo descendente, donde los datos de grupos de N líneas se promedian de alguna manera apropiada. El muestreo de puntos puede generar problemas de aliasing. – Kaz

+0

http: //unix.stackexchange.com/questions/168004/delete-every-nth-line-in-shell –

Respuesta

53

Esto es fácil de lograr con awk.

Retire cada dos líneas:

awk 'NR % 2 == 0' file > newfile 

Retire cada línea 10:

awk 'NR % 10 != 0' file > newfile 

La variable NR en AWK es el número de línea. Cualquier cosa que no sea {} en awk es un condicional, y la acción predeterminada es imprimir.

+0

Nunca escuché de awk antes. ¡Definitivamente lo verificará ahora! ¡Gracias! – Ingo

+0

Awk es muy bueno para procesar texto en scripts de shell. También puede hacer cálculos en coma flotante, lo que bash no puede hacer. Definitivamente vale la pena el tiempo de aprender para los codificadores de la carcasa. – jordanm

+1

El primer comando deja líneas con identificadores pares en su lugar, no lo elimina. Si desea eliminarlo, use awk 'NR% 2! = 0' file> newfile. – Olga

2

intentar algo como:

awk 'NR%3==0{print $0}' file 

Esto imprimirá una línea de tres. O bien:

awk 'NR%10<9{print $0}' file 

imprimirá 9 líneas de cada diez.

+1

La impresión es la acción predeterminada, por lo que 'print $ 0' no es necesario. – jordanm

+0

Lo sé. Sin embargo, me parece demasiado extraño. (No soy un usuario awk experimentado.) – Mat

+0

NR% 10 nunca podría ser más de 9 ... – 123

2

Podrías hacerlo con sed, p. Ej.

sed -n -e 'p;N;d;' file # print every other line, starting with line 1 

Si tiene sed de GNU que es bastante fácil

sed -n -e '0~10p' file # print every 10th line 
sed -n -e '1~2p' file # print every other line starting with line 1 
sed -n -e '0~2p' file # print every other line starting with line 2 
0

Puede usar un awk y un script de shell. Awk puede ser difícil, pero ...

Esto eliminará las líneas específicas que le dices que:

nawk -f awkfile.awk [filename] 

awkfile.awk contents 

BEGIN { 
if (!lines) lines="3 4 7 8" 
n=split(lines, lA, FS) 
for(i=1;i<=n;i++) 
linesA[lA[i]] 
} 
!(FNR in linesA) 

También no puedo recordar si VIM viene con el estándar de Ubuntu o no. Si no lo entiendo

continuación, abra el archivo con vim vim [nombre de archivo]

continuación, escriba

:%!awk NR\%2 or :%!awk NR\%2 

Esto eliminará cada dos líneas. Simplemente cambie el 2 a otro entero para una frecuencia diferente.

6

¿Qué tal el perl?

perl -n -e '$.%10==0&&print'  # print every 10th line 
+0

Quiere eliminar cada 10ª línea, en lugar de mantener cada 10ª línea. Cambio fácil a su código,! = En vez de ==. – jordanm

+2

No. Él declara "¿Cómo puedo ** borrar **, por ejemplo, cada segunda línea, o ** cada 9 de 10 ** líneas en el archivo?", Eliminar cada 9 de cada 10 líneas significa imprimir cada 10mo. Como usted dice, una vez que se publica la solución, es fácil adaptarse, por lo que no me he molestado en corregir otros pósters que cometieron el mismo error. – Sorpigal

+0

Después de volver a leer la pregunta, creo que su interpretación es la correcta. – jordanm

2

Esto podría funcionar para usted (GNU SED):

seq 10 | sed '0~2d' # delete every 2nd line 
1 
3 
5 
7 
9 
seq 100 | sed '0~10!d' # delete 9 out of 10 lines 
10 
20 
30 
40 
50 
60 
70 
80 
90 
100 
Cuestiones relacionadas