Frage

Ich habe einen ~ 23000 Linie SQL-Dump mehr Datenbanken im Wert von Daten enthält. Ich brauche einen bestimmten Abschnitt dieser Datei zu extrahieren (das heißt, die Daten für eine einzelne Datenbank) und es in einer neuen Datei zu platzieren. Ich weiß, dass sowohl die Start- und End-Zeilennummern der Daten, die ich will.

Kennt jemand einen Unix-Befehl (oder eine Reihe von Befehlen), um alle Zeilen aus einer Datei zwischen etwa Zeile zu extrahieren 16224 und 16482 und dann leiten Sie sie in eine neue Datei?

War es hilfreich?

Lösung

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

Von den sed Handbuch :

  

p -       Drucken Sie den Musterraum (auf die Standardausgabe). Dieser Befehl wird in der Regel nur in Verbindung mit der -n-Befehlszeilenoption verwendet wird.

     

n -       Wenn die automatische Druck nicht deaktiviert ist, drucken Sie das Musterraum, dann, unabhängig, ersetzen Sie den Musterraum mit der nächsten Eingabezeile. Wenn   gibt es nicht mehr Eingabe dann sed beendet, ohne jede weitere Verarbeitung   Befehle.

     

q -   Verlassen sed ohne Verarbeitung keine weiteren Befehle oder Eingabe.   Beachten Sie, dass der aktuelle Musterraum gedruckt wird, wenn Auto-Druck wird nicht mit der Option -n deaktiviert.

und

  

Adressen in einem sed-Skript in einer der folgenden Formen annehmen kann:

     

Nummer       eine Zeilennummer Angeben wird in der Eingabe nur diese Zeile entspricht.

     

Ein Adressbereich kann durch Angabe zwei Adressen angegeben werden   durch ein Komma (,) getrennt. Ein Adressbereich entspricht Linien ausgehend von   wo die erste Adresse übereinstimmt, und wird fortgesetzt, bis die zweite   Adresse übereinstimmt (einschließlich).

Andere Tipps

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

Wo 16224,16482 die Startzeilennummer und End-Zeilennummer sind inklusive. Dies ist ein indiziertes. -n unterdrückt die Eingabe als Ausgabe Echo, die Sie eindeutig nicht wollen; Die Zahlen geben den Zeilenbereich den folgenden Befehl operieren zu machen; der Befehl p die entsprechenden Zeilen druckt.

Ganz einfach mit Kopf / Schwanz:

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

mit sed:

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

mit awk:

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

könnten Sie verwenden 'vi' und dann den folgenden Befehl ein:

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

Alternativ:

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

EDIT: - Just Erklärung hinzuzufügen, verwenden Sie head -n 16482 angezeigt werden zunächst 16.482 Zeilen dann tail -n verwenden 258 bekommen letzten 258 Zeilen aus der erster Ausgang.

Es gibt einen anderen Ansatz mit awk:

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

Wenn die Datei sehr groß ist, kann es gut sein, nach dem exit die letzte gewünschte Zeile zu lesen. Auf diese Weise wird es die folgenden Zeilen nicht unnötig lesen:

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

sollte es tun. Der Nachteil dieses Ansatzes ist, dass Sie die Arithmetik tun müssen, das Argument für Schwanz zu bestimmen und zu berücksichtigen, ob Sie die ‚zwischen‘ gehört die Endlinie wollen oder nicht.

Schnell und schmutzig:

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

Wahrscheinlich nicht der beste Weg, es zu tun, aber es sollte funktionieren.

BTW:. 259 = 16.482 bis 16.224 + 1

Ich schrieb ein Programm Haskell genannt Splitter , das genau dies: eine lesen Sie durch meine Freilassung Blog-Post .

Sie können das Programm wie folgt verwenden:

$ cat somefile | splitter 16224-16482

Und das ist alles, was es dazu gibt. Sie Haskell brauchen, es zu installieren. Nur:

$ cabal install splitter

Und du bist fertig. Ich hoffe, dass Sie dieses Programm nützlich finden.

Auch können wir dies tun auf der Kommandozeile zu überprüfen:

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

Beispiel:

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

Mit Rubin:

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

auf den Schultern von boxxar Stehend, Ich mag diese:

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

z.

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

Die $ bedeutet „letzte Zeile“, so der erste Befehl macht sed Druck alle Linien mit Linien 16224 beginnen und der zweite Befehl machen sed beenden nach Druckzeile 16428. (Das Hinzufügen 1 für den q-Bereich in boxxar Lösung scheint nicht notwendig zu sein.)

Ich mag diese Variante, weil ich nicht zweimal das Ende Zeilennummer angeben. Und ich gemessen, dass $ verwenden, haben keine schädlichen Auswirkungen auf die Leistung.

Ich war über den Kopf / Schwanz Trick zu schreiben, aber eigentlich würde ich wahrscheinlich nur Emacs anwerfen. ; -)

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

Um die neue Ausgabedatei öffnen, ctl-y speichern

Lassen Sie uns mich sehen, was passiert.

Ich würde verwenden:

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

FNR enthält der Datensatz (Zeile) Nummer der Zeile aus der Datei gelesen werden.

Ich schrieb einen kleinen Bash-Skript, die Sie von der Kommandozeile ausgeführt werden können, so lange, wie Sie Ihre PATH aktualisieren sein Verzeichnis aufzunehmen (oder Sie können es in einem Verzeichnis abgelegt werden, die bereits im PATH enthalten ist).

Verbrauch: $ Pinch Dateiname Start-Zeilenende-line

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

Dies könnte für Sie arbeiten (GNU sed):

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

oder nutzen bash unter:

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

Ich wollte das Gleiche von einem Skript tun, um eine Variable und erreichte es durch Anführungszeichen um die Variable $ setzen Sie die Variablennamen aus dem p zu trennen:

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

Ich wollte eine Liste in separate Ordner teilen und fand die erste Frage und einen nützlichen Schritt beantworten. (Split-Befehl keine Option auf dem alte o ich Port-Code muß).

Die -n in den akzeptieren Antworten arbeiten. Hier ist eine andere Art und Weise, wenn Sie geneigt sind.

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

Dies geschieht Folgendes:

  1. Rohr in dem Inhalt einer Datei (oder im Text füttern, wie Sie wollen).
  2. sed wählt die gegebene Linie, druckt er
  3. d ist erforderlich, Zeilen zu löschen, andernfalls übernehmen sed alle Zeilen schließlich gedruckt werden. das heißt, ohne d, finden Sie alle Linien durch die gewählte Linie zweimal gedruckt gedruckt bekommen, weil Sie die $ {linenum} p Teil haben zu fragen für sie gedruckt werden. Ich bin mir ziemlich sicher, dass die -n ist im Grunde das gleiche wie das d hier tun.

Da sprechen wir über Textzeilen aus einer Textdatei zu extrahieren, werde ich einen Sonderfall geben, wo Sie alle Linien extrahieren mögen, die ein bestimmtes Muster entsprechen.

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

Wird die [Daten] Leitung und die restlichen drucken. Wenn Sie den Text von line1 das Muster mögen, geben Sie ein: sed -n '1 / Daten / p' myfile. Außerdem, wenn Sie zwei Muster wissen (besser in Ihrem Text eindeutig sein), die beide Anfang und Ende Zeile des Bereichs kann mit Streichhölzern angegeben werden.

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

Ich denke, diese nützliche Lösung sein könnte. Wenn der Tabellenname „Person“ ist, können Sie sed verwenden, um alle Zeilen, die Sie benötigen, um Ihre Tabelle wieder her.

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

Basierend auf diese Antwort , wo es die „DROP TABLE IF EXIST“ für die Tabelle fehlt die Sie wiederherstellen und müssen Sie einige Zeilen aus dem Boden der neuen Datei löschen, bevor es zu verhindern, dass mit Hilfe der folgenden Tabelle zu löschen.

Detaillierte Informationen finden Sie auch hier

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top