una texto sustituir reemplazar por numero lineas linea imprimir fmt eliminar contar con comando caracteres caracter buscar añadir unix command-line sed text-processing

sustituir - ¿Cómo puedo extraer un rango de líneas predeterminado de un archivo de texto en Unix?



sed eliminar lineas (21)

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

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

En función de esta respuesta , en la que falta la "TABLA DE GOTAS SI EXISTE" para la tabla que está restaurando y necesita eliminar algunas líneas de la parte inferior del nuevo archivo antes de usarlo para evitar eliminar la tabla siguiente.

La información detallada también se puede encontrar here

Tengo un volcado de SQL de ~ 23000 líneas que contiene varias bases de datos de datos. Necesito extraer una cierta sección de este archivo (es decir, los datos de una sola base de datos) y colocarlo en un nuevo archivo. Conozco los números de línea inicial y final de los datos que deseo.

¿Alguien sabe 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?


El -n en el trabajo acepta respuestas. Aquí hay otra manera en caso de que estés inclinado.

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

Esto hace lo siguiente:

  1. canalice el contenido de un archivo (o avance en el texto como desee).
  2. sed selecciona la línea dada, la imprime
  3. d es necesario para eliminar líneas, de lo contrario sed asumirá que todas las líneas se imprimirán. es decir, sin la d, obtendrá todas las líneas impresas por la línea seleccionada impresas dos veces porque tiene la parte $ {linenum} p que solicita que se imprima. Estoy bastante seguro de que la -n está haciendo básicamente lo mismo que la d aquí.

Escribí un pequeño script de bash que puedes ejecutar desde tu línea de comando, siempre y cuando actualices tu PATH para incluir su directorio (o puedes colocarlo en un directorio que ya está contenido en el PATH).

Uso: $ pinch nombre de archivo línea de inicio línea final

#!/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


Escribí un programa de Haskell llamado splitter que hace exactamente esto: lea mi publicación de blog de lanzamiento .

Puede utilizar el programa de la siguiente manera:

$ cat somefile | splitter 16224-16482

Y eso es todo lo que hay que hacer. Necesitarás Haskell para instalarlo. Sólo:

$ cabal install splitter

Y ya está hecho. Espero que encuentre útil este programa.


Estaba a punto de publicar el truco de cabeza / cola, pero en realidad probablemente solo arrancaría Emacs. ;-)

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

abrir el nuevo archivo de salida, ctl-y guardar

Déjame ver qué está pasando.


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

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

o aprovechando el bash:

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


Hay otro enfoque con awk :

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

Si el archivo es enorme, puede ser bueno exit después de leer la última línea deseada. De esta manera no leerá innecesariamente el archivo hasta el final:

awk ''NR==16224, NR==16482-1; NR==16482 {print; exit}'' file


Incluso podemos hacer esto para verificar en la línea de comando:

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

Por ejemplo:

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


Muy simple con la cabeza / cola:

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

utilizando sed:

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

utilizando awk:

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


Podrías usar ''vi'' y luego el siguiente comando:

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

Alternativamente:

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

EDITAR: - Solo para agregar una explicación, use head -n 16482 para mostrar las primeras 16482 líneas y luego use tail -n 258 para obtener las últimas 258 líneas de la primera salida.


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:

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

Quería dividir una lista en carpetas separadas y encontré la pregunta inicial y respondí un paso útil. (Dividir el comando no es una opción en el sistema operativo antiguo al que debo enviar el código).


Rápido y sucio:

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

Probablemente no sea la mejor manera de hacerlo pero debería funcionar.

BTW: 259 = 16482-16224 + 1.


Utilizando ruby:

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


Ya que 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 determinado patrón.

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

Imprimirá la línea [Datos] y el resto. Si desea que el texto de la línea 1 al patrón, escriba: sed -n ''1, / Data / p'' myfile. Además, si conoce dos patrones (mejor que sean únicos en su texto), tanto la línea inicial como la final del rango se pueden especificar con coincidencias.

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


Yo usaría:

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

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


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


# print section of file based on line numbers sed -n ''16224 ,16482p'' # method 1 sed ''16224,16482!d'' # method 2


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

debe hacer el truco La desventaja de este enfoque es que debe hacer la aritmética para determinar el argumento de la cola y para tener en cuenta si desea que el "entre" incluya la línea final o no.


perl -ne ''print if 16224..16482'' file.txt > new_file.txt


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

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


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

Desde el manual de sed :

p - Imprime el espacio del patrón (en la salida estándar). Este comando generalmente solo se usa junto con la opción de línea de comandos -n.

n - Si la impresión automática no está deshabilitada, imprima el espacio del patrón y, a continuación, reemplace el espacio del patrón con la siguiente línea de entrada. Si no hay más entrada, sed sale sin procesar más comandos.

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

and

Las direcciones en un script sed pueden estar en cualquiera de las siguientes formas:

Número Especificar un número de línea coincidirá solo con esa línea en la entrada.

Se puede especificar un rango de direcciones especificando dos direcciones separadas por una coma (,). Un rango de direcciones coincide con las líneas que comienzan desde donde coincide la primera dirección, y continúa hasta que la segunda dirección coincide (inclusive).