grep: Die Eingabedatei 'X' ist auch die Ausgabe

11

Ich verwende ubuntu 14.4und versuche, die Ausgabe des grepBefehls in eine Datei umzuleiten , erhalte jedoch weiterhin den folgenden Fehler:

grep: input file 'X' is also the output

Ich habe nach diesem Problem gesucht und gerade herausgefunden, dass es sich um einen Fehler handelt ubuntu 12.4und es keine Beschreibung gibt. Kann mir jemand helfen, dieses Problem herauszufinden?

Ich führe den folgenden Befehl aus:

grep -E -r -o -n r"%}(.*){%" > myfile
Kasramvd
quelle
Wenn Sie es versuchen grep pattern file > file, funktioniert es nicht. Sie können nicht dieselbe Datei als Eingabe und Ausgabe für grep verwenden.
Jimmyij
Ich füge meinen Befehl hinzu! Danke für den Hinweis, aber wenn ich versuche, eine Datei in einem anderen Pfad zu verwenden, wird dies nicht vorhergesagt und ich kann das nicht tun!
Kasramvd
zum Beispiel mit ../fi bekommen diesebash: ../f.txt: Permission denied
Kasramvd
show full command, was ist Ihre Eingabedatei oder verwenden Sie die Pipe?
Jimmyij
1
Jetzt verstehe ich, dass Sie tatsächlich rekursiv die gesamte Verzeichnisstruktur erfassen und das Ergebnis an die Datei anhängen möchten, die bereits in dieser Struktur vorhanden ist. Das Problem ist, dass die Shell (bash, zsh, was auch immer) zuerst Umleitungen ausführt und erst dann zu Befehlen zurückkehrt (in diesem Beispiel grep). Dies bedeutet, dass grepim Befehl grep pattern file > filebereits leere Dateien angezeigt werden und daher nichts als Eingabe vorhanden ist. Wenn Sie jedoch >>stattdessen verwenden, >ist die Datei nicht leer, aber grep löst trotzdem einen Fehler aus, da dies dazu führen kann, dass dieselbe Zeile (Muster) immer wieder rekursiv verarbeitet wird.
Jimmyij

Antworten:

9

Es ist nicht möglich, dieselbe Datei als Eingabe und Ausgabe für zu verwenden grep. Sie können die folgenden Alternativen in Betracht ziehen:

  • temporäre Datei

    grep pattern file > tmp_file
    mv tmp_file file
    
  • sed

    sed -i -n '/pattern/p' file
  • ganze Datei in die Variable einfügen (keine gute Idee für große Dateien)

    x=$(cat file); echo "$x" | grep pattern > file
jimmij
quelle
1
sed kann tragbarer seinsed -i '/pattern/!d' file
Costas
Aber für den Fall, dass OP willsed -i -n 's/.*\(pattern\).*/\1/p' file
Costas
@Costas Sie haben Recht, die Frage wurde bearbeitet und zusätzliche Informationen hinzugefügt, damit man auch die sedSyntax polieren kann .
Jimmyij
5

Sie können das --excludeFeld in Ihrem grepBefehl folgendermaßen verwenden:

grep  --exclude=myfile  -Eron  r"%}(.*){%"  >  myfile
Aaron Danielson
quelle
2
Stellen Sie sicher, dass myfilees eindeutig ist, da es nur für den Basisnamen der Datei gilt. Sie möchten nicht gleichnamige Dateien in anderen Verzeichnissen überspringen.
Walf
1

Ich habe einen Weg in Bash gefunden: cat >> IN_OUTPUT_FILE <<< "$(grep something IN_OUTPUT_FILE)"

Der Befehl in <<<"..."wird zuerst ausgeführt.

osexp2003
quelle