¿Cómo dividir stdout para ir a varios archivos de salida?


12

Digamos, tengo un comando commandque imprime una gran cantidad de líneas para stdout:

line1
line2
.....
lineN

Quiero guardar la salida en el disco, pero no como un solo archivo, sino como una secuencia de archivos, cada uno con 1000 líneas de stdout:

file0001.txt:
-------------
line1
....
line1000

file0002.txt:
-------------
line1001
....
line2000

etc

Traté de buscar en Google la respuesta, pero cada vez que Google me indica que teeordene, lo cual es inútil en esta situación. Probablemente, estoy ingresando consultas incorrectas.

Respuestas:


24

Una vez que haya terminado de guardar el archivo, siempre puede hacerlo spliten partes o en varios archivos según la cantidad de líneas.

split -l 1000 output_file

o incluso mejor solo intenta

command | split -l 1000 -

Esto dividirá la secuencia de salida en archivos con cada 1000 líneas (el valor predeterminado es 1000 líneas sin la opción -l).

El siguiente comando le dará flexibilidad adicional para colocar o imponer un prefijo al nombre de archivo que se generará cuando se genere la salida y se divida para almacenarla en el archivo.

command | split -l 1000 - small-


Me confundí, así que para otros, es split [arguments...] [input e.g. "-" for stdin] [output_prefix], por ejemplo: tar -c somedir | split --byes 100MB --numeric-suffixes --suffix-length=3 - somedir.tar.part-generaría un montón de archivos de 100 MB llamados somedir.tar.part-000001, 002 y así sucesivamente.
ThorSummoner

3

Puedes usar un script bash lines.bash

#!/bin/bash
a=0
while IFS='' read -r line
do
  printf -v filename "%04d.txt" "$((a++/1000))"
  echo "$line" >> $filename
done

y úsalo como:

cat long_file.txt | bash lines.bash

El único problema que noté es con el *inicio de sesión long_file.txt(alguien podría corregirlo).


2
Configure la IFScadena vacía para evitar la división de palabras read. Se usa -rpara deshabilitar la barra invertida que se escapa read. Eliminar -epara evitar que la barra invertida se escape echo. Use comillas para evitar la división de palabras echo. Utilice -ven bashdesde 4,0 a evitar el inicio de una sub-proceso. Utilice el incremento posterior ya que su código actual pondrá en el primer archivo solo 999 líneas. a=0; while IFS='' read -r line; do printf -v filename "%04d.txt" $((a++/1000)); echo "$line" >> "$filename"; done
manatwork

@manatwork Gracias. Solo que mi printfno tiene -vinterruptor. ( bash 4.2.10) Al menos no está en la página de printf
manual

1
man printfdocumentos / usr / bin / printf, que nunca en la vida podrían establecer una variable de entorno. Consulte help printfla documentación del printfshell incorporado.
manatwork

@manatwork OK. Parece que ++/todavía hay un error de sintaxis en la parte.
xralf

1
Una cosa más: no es necesario usar sigil dentro de la evaluación aritmética, a menos que necesite una expansión de parámetros explícitamente. En la expansión aritmética, las variables se evalúan de todos modos.
manatwork
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.