Wie unterscheidet man eine Datei und gibt sie aus dem Befehl aus?

32

Normalerweise würden Sie schreiben:

diff file1 file2

Ich möchte jedoch eine Datei und die Ausgabe des Befehls unterscheiden (hier mache ich den Befehl zu einem trivialen Befehl):

diff file1 <(cat file2 | sort)

Ok, dies funktioniert, wenn ich dies manuell an der Shell-Eingabeaufforderung eingebe, aber wenn ich genau die gleiche Zeile in das Shell-Skript einfüge und das Skript dann ausführe, wird eine Fehlermeldung angezeigt.

Die Frage ist also, wie man das richtig macht.

Natürlich möchte ich vermeiden, die Ausgabe in eine temporäre Datei zu schreiben.

Greenoldman
quelle

Antworten:

39

Ich vermute, dass Ihr Skript und Ihre Shell unterschiedlich sind. Vielleicht haben Sie ganz #!/bin/shoben in Ihrem Skript den Dolmetscher, aber Sie verwenden ihn bashals Ihre persönliche Shell. Sie können herausfinden, welche Shell Sie in einem Terminal ausführen, indem Sie ausführen echo $SHELL.

Eine einfachere Methode, die für die meisten Shells funktionieren sollte, ist die Verwendung einer Pipe-Umleitung anstelle des von Ihnen angegebenen Dateileseoperators. Das Symbol '-' ist eine Standardnomenklatur zum Lesen von STDIN und kann häufig als Ersatz für einen Dateinamen in einer Argumentliste verwendet werden:

cat file2 | sort | diff file1 -

Oder um unnötigen Gebrauch von cat zu vermeiden :

sort < file2 | diff file1 -
Caleb
quelle
Ah, Sie sind in der Tat gut, ich habe nicht überprüft, ob Sie schüchtern sind oder nicht. Vielen Dank für die Lösung.
Greenoldman
Es ist eine andere Datei mit stdout. Nun, wie kann man stdout mit einer Datei unterscheiden? Ich meine, die entgegengesetzte Richtung. es ist -Rim Falle der Verwendunggit diff --no-index
Nakilon
@Nakilon Sie würden nur das Argument Reihenfolge ändern: diff - file1.
Caleb
Cool. Das hat nicht funktioniert git diff.
Nakilon
@Nakilon Natürlich nicht, warum sollte es? git diffist eine völlig andere Bestie und verarbeitet Verweise auf Glob-Objekte in ihrem internen Index, nicht auf Dateien. diffarbeitet auf dem Dateisystem. Die -Syntax ist nur Shell-syntaktischer Zucker für /dev/stdindie Datei, die den STDIN-Stream darstellt. Deshalb diffkann es als Ersatz für einen Dateinamen verwendet werden. Währenddessen git diffsucht er nicht nach Dateien, sondern sucht nach Objekten, sodass Sie ihm etwas übergeben müssen, das er erkennt. Verwenden Sie es nicht, um Dateien miteinander zu vergleichen, verwenden Sie es diffdafür.
Caleb
-4

Der Umfang der Standardeingabe ist das Skript selbst. Platzieren Sie Ihren Code also einfach in einem Block wie folgt:

{
  diff file1 <(sort file2)
}

Auf diese Weise befindet sich der Bereich der STDIN innerhalb des Blocks.

Ich habe es versucht und es funktioniert.

mähen
quelle
Das ist keine Funktion, es ist ein Block und es macht keinen Unterschied.
Gilles 'SO- hör auf, böse zu sein'
@gilles Thx für die Korrektur. Übrigens habe ich es selbst versucht und es funktioniert. Hast du?
Heute,
3
Der Block hat keinen Einfluss auf die Gültigkeit des <(…)Konstrukts. Ihr Skript funktioniert oder nicht, je nachdem, ob Sie es in einer Shell ausführen, die dies unterstützt <(…)oder nicht (ksh93 / bash / zsh vs Bourne / ash / kshk88). Calebs Antwort macht alles klar.
Gilles 'SO- hör auf böse zu sein'
1
@ Gilles ok, danke für die Erklärung.
26.