Wie kopiere ich selektiv Details aus einer Datei und füge sie in eine neue Datei ein?

11

Ich habe eine Datei mit meinen persönlichen Daten (.txt). Wie kann ich über das Terminal nur wenige Details aus der Datei kopieren und in eine neue .txtDatei einfügen?

Wenn dies beispielsweise der Inhalt der Datei ist:

name : farah age : 23 phone number : 0123 education : degree

Wie kann ich nur Alter und Telefonnummer kopieren und in eine neue .txtDatei ausgeben ?

MsWanie
quelle
2
Dies hängt davon ab, was in die neue Datei kopiert werden soll. Möchten Sie die ersten Zeilen, die letzten Zeilen, die eine Zeichenfolge enthalten, keine Zeichenfolge, Zeilen zwischen zwei Zeichenfolgen? Es gibt Tools, um all dies zu tun, aber wir müssen wissen, was Sie tun möchten.
Arcege

Antworten:

7

Es gibt verschiedene Möglichkeiten, dies zu tun. Wenn Ihre Datei eine bekannte Struktur hat, können Sie verwenden grep. Der grepBefehl durchsucht eine Datei nach einer bestimmten Phrase und gibt Zeilen zurück, die dieser Phrase entsprechen. Also, wenn Ihre Datei aussieht

Name: Sally

Geburtsdatum: 7.31.76

Adresse: 1234 Main St.

SSN: 123-45-6789

Sie können laufen grep Name info.txtund es wird zurückkehren Name: Sally. Sie können die Ausgabe dann in eine andere Datei umleiten . Also anrufen

grep Name info.txt > info2.txt

gibt die Zeile in die neue Datei info2.txt aus. Wenn Sie neue Zeilen anhängen möchten, können Sie dies tun

grep Address info.txt >> info2.txt

Andernfalls wird die Datei überschrieben.

Sie können auch lernen, einen Befehlszeilentexteditor wie vim zu verwenden.

Kris Harper
quelle
2

Mit grep können Sie in details.txt nach einem regulären Ausdruck suchen und das Ergebnis in die neue Datei umleiten.

Wenn alle Zeilen, die Sie kopieren möchten, etwas gemeinsam haben, können Sie die anderen Zeilen nicht verwenden:

grep "string in common" details.txt > new.txt

Wenn nicht , werden Sie möchten , suchen müssen für jede Zeile kopieren, noch grep, und hängen Sie sie an new.txt Verwendung >>anstelle von >.

danjjl
quelle
1

Es gibt auch Editoren, die im Terminal arbeiten, z. B. Nano, Vi und Emacs.

Wenn Sie eine grafische Benutzeroberfläche auf Ihrem lokalen Computer und ein Terminal auf einem Remotecomputer verwenden, können Sie auch mit der Maus von einem Terminalfenster / einer Registerkarte in ein zweites kopieren und einfügen.

Elmicha
quelle
1

Angenommen, die Eingabedatei details.txtenthält:

name: farah
age: 23
phone number: 0123
education: degree

Sie können die Zeilen "Name" und "Telefon" durch erweitertes Grep auswählen und die Ausgabe an new.txt umleiten:

grep -E "age:|phone number:" details.txt > new.txt

Dies erzeugt new.txt mit:

age: 23
phone number: 0123

Wie es funktioniert:

Grep druckt nur übereinstimmende Linien. Die -EOptionen aktivierten den erweiterten regulären Ausdruck, der Ihnen die Möglichkeit zur Verwendung bietet |(alternativ). Denken Sie daran, das gesamte Muster zu zitieren, damit |es von grep interpretiert wird. Andernfalls versucht die Shell zu interpretieren. Das willst du hier nicht.

Michał Šrajer
quelle
1

Die von Ihnen angezeigte Datei enthält alle Details in einer Zeile:

name : farah age : 23 phone number : 0123 education : degree

Ich habe angenommen, dass Sie age :usw. in den Befehl fest codieren können , aber der darauf folgende Text variiert und dass die Details möglicherweise nicht in der angegebenen Reihenfolge oder zusammenhängend sind.

Sie können Teile der Zeile mit grepdem -oFlag von ' extrahieren . Dadurch wird nur der übereinstimmende Teil und nicht die gesamte Zeile gedruckt.

Wenn Sie die age :und phone number :Teile einschließen möchten , können Sie entweder das -eFlag verwenden, um mehrere Übereinstimmungen anzugeben, oder alternieren.

$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123

Der Ausdruck [^ ]*bedeutet eine beliebige Anzahl von Zeichen, die kein Leerzeichen sind, sodass Zeichen nach age :dem nächsten Leerzeichen übereinstimmen .

Ersetzen Sie filedurch den Namen der Datei, die Ihre Daten enthält. Sie können die neue Datei schreiben, indem Sie die Ausgabe mit dem >Operator wie folgt in eine neue Datei umleiten :

grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile

Wenn Sie dies tun, sehen Sie keine Ausgabe. Sie sollten zuerst die Ausgabe überprüfen und dann die Umleitung hinzufügen.

Hier ist das Beispiel mit Wechsel. Wir verwenden das -EFlag, grepum anzugeben, dass ein erweiterter regulärer Ausdruck verwendet werden soll. Die Syntax lautet (pattern1|pattern2)- dies stimmt überein pattern1und / oder pattern2. Wenn eines gefunden wird, wird es gedruckt (unabhängig davon, ob das andere gefunden wird oder nicht). Ich verwende jetzt die +Bedeutung mindestens eines der vorhergehenden Zeichen, anstatt *null oder mehr des vorhergehenden Zeichens zu bedeuten. In diesem Zusammenhang funktionieren beide gleich gut.

$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23 
phone number : 0123 

Wenn Sie die age :und phone number:Teile weglassen möchten , können Sie das -PFlag verwenden, um grepnach Perl-kompatiblen regulären Ausdrücken zu fragen . Dies unterstützt den Wechsel und auch eine Möglichkeit, Text nach einem bestimmten Muster abzugleichen:

$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123

Wenn Sie den Text anders formatieren möchten, können Sie beispielsweise Folgendes verwenden sed:

$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123

Dies hängt davon ab , ob Sie agevorher phone numberkommen. Passen Sie dies entsprechend an, wenn dies nicht der Fall ist. Wenn Sie sich nicht auf die Reihenfolge verlassen können, können Sie diesen sehr komplizierten Befehl verwenden:

$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23

Dadurch wird die Zeile neu angeordnet, sodass der phone number :Abschnitt in jeder Zeile an erster Stelle steht. Anschließend wird ein zweiter Austausch durchgeführt, um die gewünschten Details auszuwählen. Die hier verwendete Technik verdanke ich dieser Antwort von Muru .

Hinweise zu sedBefehlen, die in den vorherigen Erläuterungen nicht behandelt wurden

  • -rVerwenden Sie erweiterte Regex für besser lesbare Befehle (GNU sedversteht -Emit der gleichen Bedeutung)
  • s/old/new/ersetzen olddurchnew
  • (pattern)Speichert, patternum später mit \1oder \2usw. zu referenzieren (entsprechend der Reihenfolge von links nach rechts, in der die Erfassungsgruppen auftreten - beachten Sie, dass sednur bis zu 7 davon enthalten sind!).
  • .Ein beliebiges Zeichen steht daher .*für eine beliebige Anzahl beliebiger Zeichen.
  • ; trennt Befehle wie in der Shell.
Zanna
quelle