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.
-n
suprime 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 comandop
imprime 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.sql
y el comando awk debería serawk 'NR>=16224&&NR<=16482' in.sql > out.sql
head -16482 in.sql | tail -$((16482-16224)) >out.sql
el cálculo se reduce a bashtail -n +16224
para 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
cat
comando;head
Puede 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
exit
despué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}' file
fuente
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
cat
comando;head
Puede 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 quesed
imprimir todas las líneas que comienzan con la línea16224
y la segunda marcas comandosed
dejar de fumar después de imprimir una línea16428
. ( No parece necesario agregar1
para elq
rango 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.sql
fuente
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
splitter
Solo lee desde la entrada estándar? En cierto sentido, no importa; elcat
comando es superfluo si lo hace o no. Utilicesplitter 16224-16482 < somefile
o (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
cat
comando en ninguno de estos;sed
es 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
wc
comando, 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:
-s
suprime la salida de diagnóstico; Los comandos reales están en una cadena aquí. Específicamente,16224,16482p
ejecuta elp
comando (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 | sed
está mejor escrita comosed file
Como 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