Tengo un volcado de SQL de ~ 23000 líneas que contiene varias bases de datos de datos. Necesito extraer una determinada sección de este archivo (es decir, los datos de una sola base de datos) y colocarla en un nuevo archivo. Sé los números de línea de inicio y fin de los datos que quiero.
¿Alguien conoce un comando de Unix (o una serie de comandos) para extraer todas las líneas de un archivo entre la línea 16224 y 16482 y luego redirigirlas a un nuevo archivo?
unix
command-line
sed
text-processing
Adam J. Forster
fuente
fuente

Respuestas:
Del manual de sed :
y
fuente
sed -n '16224,16482p;16483q' filename. De lo contrario, sed seguirá escaneando hasta el final (o al menos mi versión lo hace).Donde 16224,16482 son el número de línea inicial y el número de línea final, inclusive. Esto es 1 indexado.
-nsuprime el eco de la entrada como salida, que claramente no desea; los números indican el rango de líneas para operar el siguiente comando; El comandopimprime las líneas relevantes.fuente
sed -n '16224,16482p;16482q' orig-data-file > new-file.Muy simple usando cabeza / cola:
usando sed:
usando awk:
fuente
tail.sed -n 16224,16482p' in.sql >out.sqly el comando awk debería serawk 'NR>=16224&&NR<=16482' in.sql > out.sqlhead -16482 in.sql | tail -$((16482-16224)) >out.sqlel cálculo se reduce a bashtail -n +16224para reducir la computaciónPuede usar 'vi' y luego el siguiente comando:
Alternativamente:
EDITAR: - Solo para agregar una explicación, usa head -n 16482 para mostrar las primeras 16482 líneas y luego usa tail -n 258 para obtener las últimas 258 líneas de la primera salida.
fuente
catcomando;headPuede leer un archivo directamente. Esto es más lento que muchas alternativas porque usa 2 comandos (3 como se muestra) donde 1 es suficiente.cat). Otras soluciones necesitan al menos unos minutos. También parece ser la variación más rápida en GNUtail -n +XXX filename | head XXX.Hay otro enfoque con
awk:Si el archivo es enorme, puede ser bueno
exitdespués de leer la última línea deseada. De esta manera, no leerá las siguientes líneas innecesariamente:fuente
print; exit. Gracias !awk 'NR==16224, NR==16482; NR==16482 {exit}' filefuente
fuente
debería hacer el truco. La desventaja de este enfoque es que necesita hacer la aritmética para determinar el argumento de la cola y tener en cuenta si desea que el 'intermedio' incluya o no la línea final.
fuente
catcomando;headPuede leer un archivo directamente. Esto es más lento que muchas alternativas porque usa 2 comandos (3 como se muestra) donde 1 es suficiente.| tail -$((16482 - 16224)).De pie sobre los hombros de boxxar, me gusta esto:
p.ej
Los
$medios "última línea", por lo que el primer comando hace quesedimprimir todas las líneas que comienzan con la línea16224y la segunda marcas comandoseddejar de fumar después de imprimir una línea16428. ( No parece necesario agregar1para elqrango en la solución de boxxar).Me gusta esta variante porque no necesito especificar el número de línea final dos veces. Y medí que el uso
$no tiene efectos perjudiciales en el rendimiento.fuente
sed -n '16224,16482p' < dump.sqlfuente
Rápido y sucio:
Probablemente no sea la mejor manera de hacerlo, pero debería funcionar.
Por cierto: 259 = 16482-16224 + 1.
fuente
Escribí un programa de Haskell llamado splitter que hace exactamente esto: leer mi publicación de blog de lanzamiento .
Puede usar el programa de la siguiente manera:
Y eso es todo lo que hay que hacer. Necesitarás Haskell para instalarlo. Sólo:
Y ya terminaste. Espero que este programa te sea útil.
fuente
splitterSolo lee desde la entrada estándar? En cierto sentido, no importa; elcatcomando es superfluo si lo hace o no. Utilicesplitter 16224-16482 < somefileo (si toma argumentos de nombre de archivo)splitter 16224-16482 somefile.Incluso podemos hacer esto para verificar en la línea de comando:
Por ejemplo:
fuente
catcomando en ninguno de estos;sedes perfectamente capaz de leer archivos por sí solo, o puede redirigir la entrada estándar de un archivo.Usando ruby:
fuente
Estaba a punto de publicar el truco de cabeza / cola, pero en realidad probablemente solo dispararía emacs. ;-)
abra el nuevo archivo de salida, ctl-y guardar
A ver qué pasa.
fuente
Yo usaría:
FNR contiene el número de registro (línea) de la línea que se lee desde el archivo.
fuente
Quería hacer lo mismo desde un script usando una variable y lo logré poniendo comillas alrededor de la variable $ para separar el nombre de la variable de la p:
Quería dividir una lista en carpetas separadas y encontré la pregunta inicial y respondí un paso útil. (el comando dividido no es una opción en el sistema operativo anterior al que tengo que transferir el código).
fuente
Escribí un pequeño script bash que puede ejecutar desde su línea de comando, siempre que actualice su RUTA para incluir su directorio (o puede colocarlo en un directorio que ya está contenido en la RUTA).
Uso: $ pinch nombre_archivo inicio-línea final-línea
fuente
wccomando, que desperdicia el ancho de banda del disco, especialmente en archivos de gigabytes. En todo tipo de formas, esto está bien documentado, pero también es un exceso de ingeniería.Esto podría funcionar para usted (GNU sed):
o aprovechando bash:
fuente
Usando ed:
-ssuprime la salida de diagnóstico; Los comandos reales están en una cadena aquí. Específicamente,16224,16482pejecuta elpcomando (imprimir) en el rango de dirección de línea deseado.fuente
El -n en las respuestas aceptadas funciona. Aquí hay otra forma en caso de que esté inclinado.
Esto hace lo siguiente:
fuente
cat file | sedestá mejor escrita comosed fileComo estamos hablando de extraer líneas de texto de un archivo de texto, le daré un caso especial en el que desea extraer todas las líneas que coincidan con un patrón determinado.
Imprimirá la línea [Datos] y el resto. Si desea el texto de la línea 1 al patrón, escriba: sed -n '1, / Data / p' myfile. Además, si conoce dos patrones (es mejor que sea único en su texto), tanto la línea inicial como la final del rango se pueden especificar con coincidencias.
fuente