Pregunta

Tengo un ~23000 línea volcado SQL que contiene varias bases de datos de la pena de datos.Necesito extraer una cierta sección de este archivo (es decir,los datos de una sola base de datos) y colóquelo en un nuevo archivo.Sé el inicio y el final de la línea de los números de los datos que quiero.

¿Alguien sabe de un comando de Unix (o una serie de comandos) para extraer todas las líneas de un archivo entre decir la línea de 16224 y 16482 y luego redireccionar a un archivo nuevo?

¿Fue útil?

Solución

sed -n '16224,16482p;16483q' filename > newfile

A partir de la sed manual:

p - Imprima el patrón espacial (a la salida estándar).Este comando es generalmente sólo se utiliza junto con la opción-n opción de línea de comandos.

n - Si de auto-impresión no está desactivado, la impresión del patrón de espacio, a continuación, independientemente, reemplace el espacio en el patrón con la siguiente línea de entrada.Si no hay más a la entrada, a continuación, sed sale sin procesar más los comandos.

q - Salida sed sin procesar más o comandos de entrada.Tenga en cuenta que el actual patrón de espacio se imprime si de auto-impresión no está deshabilitado con la opción-n.

y

Direcciones en una sed de secuencia de comandos puede ser en cualquiera de las siguientes formas:

número de La especificación de un número de línea sólo coincidirá con esa línea en la entrada.

Un rango de direcciones puede ser especificado mediante la especificación de dos direcciones separados por una coma (,).Un rango de direcciones de los partidos de líneas a partir de donde la primera dirección de los partidos, y continúa hasta el segundo la dirección de los partidos (inclusive).

Otros consejos

sed -n '16224,16482 p' orig-data-file > new-file

Donde 16224,16482 son el inicio número de línea y el final de la línea número, inclusive.Este es 1-indexada. -n suprime el eco de la entrada como de salida, que claramente no quieren;los números indican el rango de las líneas para hacer el siguiente comando operar;el comando p imprime las líneas relevantes.

Bastante simple de usar en la cabeza/cola:

head -16482 in.sql | tail -258 > out.sql

el uso de sed:

sed -n '16482,16482p' in.sql > out.sql

el uso de awk:

awk 'NR>=10&&NR<=20' in.sql > out.sql

Usted podría utilizar 'vi' y, a continuación, el siguiente comando:

:16224,16482w!/tmp/some-file

Alternativamente:

cat file | head -n 16482 | tail -n 258

EDIT:- Sólo para agregar explicación, utilice head-n 16482 para mostrar el primer 16482 líneas, a continuación, utilizar tail-n 258 para obtener el último 258 líneas de salida de la primera salida.

Existe otro enfoque con awk:

awk 'NR==16224, NR==16482' file

Si el archivo es enorme, puede ser una buena idea exit después de leer la última línea deseada.De esta manera, no va a leer las siguientes líneas innecesariamente:

awk 'NR==16224, NR==16482-1; NR==16482 {print; exit}' file
perl -ne 'print if 16224..16482' file.txt > new_file.txt
 # print section of file based on line numbers
 sed -n '16224 ,16482p'               # method 1
 sed '16224,16482!d'                 # method 2

sed -n '16224,16482p' < dump.sql

cat dump.txt | head -16224 | tail -258

debe hacer el truco.La desventaja de este enfoque es que usted necesita para hacer la media aritmética para determinar el argumento para la cola y a cuenta de si usted quiere que el 'entre' para incluir el final de la línea o no.

Rápido y sucio:

head -16428 < file.in | tail -259 > file.out

Probablemente no es la mejor manera de hacerlo, pero se debe trabajar.

BTW:259 = 16482-16224+1.

Escribí un programa llamado Haskell splitter que hace exactamente este:tiene un leer a través de mi liberación blog.

Usted puede utilizar el programa como sigue:

$ cat somefile | splitter 16224-16482

Y eso es todo lo que hay que hacer.Usted necesitará Haskell para instalarlo.Solo tienes que:

$ cabal install splitter

Y listo.Espero que encuentre usted este programa de utilidad.

Incluso podemos hacer esto para comprobar en línea de comandos:

cat filename|sed 'n1,n2!d' > abc.txt

Por Ejemplo:

cat foo.pl|sed '100,200!d' > abc.txt

El uso de ruby:

ruby -ne 'puts "#{$.}: #{$_}" if $. >= 32613500 && $. <= 32614500' < GND.rdf > GND.extract.rdf

De pie sobre los hombros de boxxar, me gusta este:

sed -n '<first line>,$p;<last line>q' input

por ejemplo,

sed -n '16224,$p;16482q' input

El $ significa "última línea", por lo que el primer comando que hace sed imprimir todas las líneas que comienzan con la línea 16224 y el segundo comando hace sed dejar de fumar después de línea de impresión 16428.(La adición de 1 para el q-rango en boxxar la solución no parece ser necesario.)

Me gusta esta variante porque no necesito para especificar el final de la línea número dos veces.Y me ha medido que el uso de $ no tiene efectos perjudiciales sobre el rendimiento.

Yo estaba a punto de publicar la cabeza/cola truco, pero en realidad yo probablemente sólo el fuego de emacs.;-)

  1. esc-x goto-line ret 16224
  2. marca (ctrl-espacio)
  3. esc-x goto-line ret 16482
  4. esc-w

abra el nuevo archivo de salida, ctl-y guardar

Vamos a ver lo que está sucediendo.

Me gustaría utilizar:

awk 'FNR >= 16224 && FNR <= 16482' my_file > extracted.txt

FNR contiene el registro (línea) número de la línea que se leen desde el archivo.

Escribí un pequeño script en bash que se puede ejecutar desde la línea de comandos, mientras que la actualización de la RUTA de acceso incluyen su directorio (o se puede colocar en un directorio que ya está contenida en la RUTA).

Uso:$ pizca de nombre de archivo de inicio de línea fin de línea

#!/bin/bash
# Display line number ranges of a file to the terminal.
# Usage: $ pinch filename start-line end-line
# By Evan J. Coon

FILENAME=$1
START=$2
END=$3

ERROR="[PINCH ERROR]"

# Check that the number of arguments is 3
if [ $# -lt 3 ]; then
    echo "$ERROR Need three arguments: Filename Start-line End-line"
    exit 1
fi

# Check that the file exists.
if [ ! -f "$FILENAME" ]; then
    echo -e "$ERROR File does not exist. \n\t$FILENAME"
    exit 1
fi

# Check that start-line is not greater than end-line
if [ "$START" -gt "$END" ]; then
    echo -e "$ERROR Start line is greater than End line."
    exit 1
fi

# Check that start-line is positive.
if [ "$START" -lt 0 ]; then
    echo -e "$ERROR Start line is less than 0."
    exit 1
fi

# Check that end-line is positive.
if [ "$END" -lt 0 ]; then
    echo -e "$ERROR End line is less than 0."
    exit 1
fi

NUMOFLINES=$(wc -l < "$FILENAME")

# Check that end-line is not greater than the number of lines in the file.
if [ "$END" -gt "$NUMOFLINES" ]; then
    echo -e "$ERROR End line is greater than number of lines in file."
    exit 1
fi

# The distance from the end of the file to end-line
ENDDIFF=$(( NUMOFLINES - END ))

# For larger files, this will run more quickly. If the distance from the
# end of the file to the end-line is less than the distance from the
# start of the file to the start-line, then start pinching from the
# bottom as opposed to the top.
if [ "$START" -lt "$ENDDIFF" ]; then
    < "$FILENAME" head -n $END | tail -n +$START
else
    < "$FILENAME" tail -n +$START | head -n $(( END-START+1 ))
fi

# Success
exit 0

Esto podría funcionar para usted (GNU sed):

sed -ne '16224,16482w newfile' -e '16482q' file

o tomar ventaja de bash:

sed -n $'16224,16482w newfile\n16482q' file

Yo quería hacer lo mismo desde una secuencia de comandos utilizando una variable y lo ha logrado por poner comillas alrededor de los $variable para separar el nombre de la variable a partir de la p:

sed -n "$first","$count"p imagelist.txt >"$imageblock"

Yo quería dividir una lista en carpetas separadas y se encontró a la pregunta inicial y responder a un paso útil.(comando dividir no es una opción en el viejo os tengo a puerto de código).

La -n en la acepte respuestas trabajo.He aquí otra manera en caso de que usted está inclinado.

cat $filename | sed "${linenum}p;d";

Esto hace lo siguiente:

  1. de la tubería en el contenido de un archivo (o se alimentan en el texto que usted desee).
  2. sed selecciona la línea dada, lo imprime
  3. d es necesario para eliminar líneas, de lo contrario la sed asumirá todas las líneas eventualmente será impreso.es decir, sin la d, obtendrá todas las líneas impresas por la línea seleccionada se imprime dos veces, porque tienes el ${linenum}p parte pidiendo a ser impreso.Estoy bastante seguro de que la opción-n hace básicamente lo mismo que el d aquí.

Ya que estamos hablando de la extracción de líneas de texto de un archivo de texto, voy a dar un caso especial en el que desea extraer todas las líneas que coincidan con un determinado patrón.

myfile content:
=====================
line1 not needed
line2 also discarded
[Data]
first data line
second data line
=====================
sed -n '/Data/,$p' myfile

Imprimir los [Datos] de la línea y el resto.Si desea que el texto de la línea1 del patrón, escribe:sed-n '1,/Data/p' miarchivo.Además, si dos o patrón (mejor ser único en su texto), el principio y el final de la línea de la gama puede ser especificado con los partidos.

sed -n '/BEGIN_MARK/,/END_MARK/p' myfile

Creo que esto podría ser útil solución.Si el nombre de la tabla es "persona" se puede utilizar la sed de obtener todas las líneas que usted necesita para restaurar su mesa.

sed -n -e '/DROP TABLE IF EXISTS.*`person `/,/UNLOCK TABLES/p' data.sql  > new_data.sql

Basado en esta respuesta, donde lo que falta es el "DROP TABLE IF EXIST" de la tabla son la restauración y que usted necesita para eliminar algunas líneas de la parte inferior del archivo nuevo antes de usarlo para evitar que se borren de la siguiente tabla.

La información detallada puede encontrarse también aquí

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top