Tengo un archivo CSV bastante considerable (75 MB). Solo estoy tratando de producir un gráfico, así que realmente no necesito todos los datos.
Reescritura: me gustaría eliminar n líneas, luego mantener una línea, luego eliminar n líneas, y así sucesivamente.
Entonces, si el archivo se ve así:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
yn = 2, entonces la salida sería:
Line 3
Line 6
Parece que sed
podría hacer esto, pero no he podido entender cómo. Un comando bash sería ideal, pero estoy abierto a cualquier solución.
Respuestas:
NR
La variable (número de registros) es el número de registros de líneas porque el comportamiento predeterminado es una nueva línea paraRS
(separador de registros). El patrón y la acción son opcionales en el formato predeterminado de awk'pattern {actions}'
. cuando damos solo una parte del patrón,awk
escribe todos los campos$0
para lastrue
condiciones de nuestro patrón .fuente
awk 'NR == 1 || NR % 3 == 0'
awk 'NR == 1 || NR % 2 == 0' myfile.txt | wc -l
resultado de un número impar mientras que el archivo original tenía un número par de líneas. La respuesta @kev funciona mejor en mi caso de prueba.sed
También puede hacer esto:man sed
explica~
como:fuente
1p
imprime la primera línea,0~3p
imprime cada tercera línea a partir de la línea 3 (por lo1p
tanto, se requiere para imprimir la línea 1). Pero tenga en cuenta que0~3
no es estándar sino una extensión sed de GNU.sed -n '1p;0~10p' '.\in.txt' > out.txt
para imprimir el archivo reducido en un archivo de salida.Perl también puede hacer esto:
Este programa imprimirá la primera línea de su entrada, y cada tercera línea después.
Para explicarlo un poco,
<>
es el operador de entrada de línea, que itera sobre las líneas de entrada cuando se usa en unwhile
bucle como este. La variable especial$.
contiene el número de líneas leídas hasta ahora, y%
es el operador de módulo.Este código se puede escribir de manera aún más compacta como una línea, utilizando los interruptores
-n
y-e
:El
-e
conmutador toma una parte del código Perl para ejecutarse como un parámetro de línea de comando, mientras que el-n
conmutador envuelve implícitamente el código en unwhile
bucle como el que se muestra arriba.Editar: para obtener realmente las líneas 1, 3, 6, 9, ... como en el ejemplo, en lugar de las líneas 1, 4, 7, 10, ... como supuse por primera vez que quería, reemplace
$. % 3 == 1
con$. == 1 or $. % 3 == 0
.fuente
Si quieres hacerlo con un script Bash puedes probar:
Guárdelo como "read_lines.sh" y recuerde dar permisos + x al archivo bash.
fuente
./read_lines.sh > new_file.txt
.Una solución en bash puro, que no genera un proceso es:
La primera línea omite 2 líneas al comienzo del archivo, y luego
while
imprime la siguiente línea y omite 2 líneas nuevamente.Si su archivo es pequeño, esta es una forma muy eficiente de hacer el trabajo, ya que no inicia un proceso. Cuando su archivo es grande,
sed
debe usarse ya que es más eficiente en el manejo de io quebash
.fuente
Una versión de Python (tanto Python 2 como Python 3):
reemplace
[::3]
con parámetros de inicio, finalización y tamaño de paso para obtener más control. Por ejemplo,[10:36:5]
pone las líneas 10,15, ..., 35.Tenga en cuenta que, dado que
readlines()
mantiene las terminaciones de línea, la salida de esta llamada puede terminar con una última línea vacía, a menos que la última línea original se elimine por el tamaño de paso elegido.También es posible una versión de transmisión (aquí solo se muestra después de la transmisión terminada):
fuente