¿Cómo dividir un archivo grande en dos partes, en un patrón?
Dado un ejemplo file.txt:
ABC
EFG
XYZ
HIJ
KNL
Quiero dividir este archivo en XYZtal que file1contenga líneas hasta XYZy el resto de las líneas file2.
text-processing
sed
awk
split
d.putto
fuente
fuente

XYZincluirse la línea en la salida o no?Respuestas:
Con
awkusted puede hacer:Explicación: El primer
awkargumento (out=file1) define una variable con el nombre de archivo que se utilizará para la salida mientraslargefilese procesa el argumento posterior ( ). Elawkprograma imprimirá todas las líneas en el archivo especificado por la variableout({print >out}). Si se encuentra el patrónXYZ, la variable de salida se redefinirá para que apunte al nuevo archivo ({out="file2}") que se utilizará como destino para imprimir las líneas de datos posteriores.Referencias
fuente
Este es un trabajo para
csplit:sería
silently dividir el archivo, creando piezas con prefIXfileynumbered utilizando un solo dígito, por ejemplo,file0etc Tenga en cuenta que el uso de/regex/partiría hasta, pero sin incluir la línea que coincidenciasregex. Para dividir e incluir la coincidencia de línea,regexagregue un+1desplazamiento:Esto crea dos archivos
file0yfile1. Si realmente necesita que se nombrenfile1yfile2siempre puede agregar un patrón vacío alcsplitcomando y eliminar el primer archivo:crea
file0,file1yfile2aunquefile0está vacío para que pueda quitar de forma segura:fuente
Con un moderno,
kshaquí hay una variante de shell (es decir, sinsed) de una de lassedrespuestas basadas arriba:Y otra variante en
kshsolo (es decir, también omitiendocat):(La
kshsolución pura parece ser bastante eficaz; en un archivo de prueba de 2.4 GB necesitaba 19-21 segundos, en comparación con 39-47 segundos con el enfoquesed/catbasado).fuente
readyprint, simplemente debe dejarlo ir a la salida por sí solo. El rendimiento mejora si construye el conjunto de herramientas AST por completo ykshcompila todos los componentes incorporados; es extraño para mí quesedno sea uno de ellos, en realidad. Pero con cosas comowhile <file dosupongo que no es necesariosedtanto ...awkdesempeñó en su punto de referencia? Y aunque estoy bastante seguro dekshque siempre ganará esta pelea, si está utilizando un GNU con elsedque no es muy justosed:-unbuffered de GNU es un enfoque pobre para POSIXLY garantizar que el desplazamiento del descriptor se deja donde el programa se cerró - no debería ser necesario ralentizar el funcionamiento regular del programa - el almacenamiento en búfer está bien - todo lo queseddebe hacer es buscar el descriptor cuando haya terminado. Por alguna razón, GNU revierte esa mentalidad.while; la impresión se realiza implícitamente como el efecto secundario definido del<##operador de redireccionamiento. Y solo se necesita imprimir la línea correspondiente. (De esa forma, la implementación de la función de shell es más flexible para admitir incl./excl.) Unwhileciclo explícito que esperaría que fuera significativamente más lento (pero no lo he verificado).headlugar de laread; parece que sólo un poco más lento, pero más concisa de código:{ head -1 <##XYZ ; { read <##"" ;} >file4 ;} <largefile >file3.Con GNU
seddeberías usar el-uinterruptor nbuffered. Sinsedembargo, la mayoría de los otros s deberían funcionar.Para dejar a XYZ afuera ...
fuente
Prueba esto con GNU sed:
fuente
sed -e '1,/XYZ/{w file1' -e 'd}' large_file > file2Un truco fácil es imprimir ya sea en STDOUT o STDERR, dependiendo de si el patrón de destino ha coincidido. Luego puede usar los operadores de redirección del shell para redirigir la salida en consecuencia. Por ejemplo, en Perl, suponiendo que se llama al archivo de entrada
fy los dos archivos de salidaf1yf2:Descartando la línea que coincide con el patrón dividido:
Incluyendo la línea coincidente:
Alternativamente, imprima en diferentes identificadores de archivo:
Descartando la línea que coincide con el patrón dividido:
Incluyendo la línea coincidente:
fuente