Ich teste ein paar Dinge in Bash und habe beschlossen, die Anzahl der Zeilen in der Datei mit der Anzahl der eindeutigen Zeilen zu vergleichen. Ich weiß, dass ich einfach zwei temporäre Variablen erstellen kann, die die entsprechenden Werte speichern und sie dann vergleichen, aber ich habe mich gefragt, wie ich das in einer Zeile machen kann.
Ich dachte zum Beispiel, dieser Ansatz würde funktionieren: test `wc -l filename` -eq `uniq filename|wc -l`
. Ich erhalte die Fehlermeldung -bash: test: too many arguments
. Wo liegt mein Fehler und wie würden Sie es machen, ohne temporäre Variablen zu verwenden?
Antwort1
Sie können keinen direkten Vergleich durchführen, da nur und wc -l file
ausgibt . Sie können es wie von @stelldriver vorgeschlagen machen und die Datei mit auf die Standardeingabe von umleiten , sodass nur ausgegeben wird, oder awk verwenden, um nur das erste Feld zu erhalten (siehe unten).[number] file
uniq file | wc -l
[number]
wc
wc -l < file
[number]
Außerdem beeinträchtigen Backticks die Lesbarkeit. Bevorzugen Sie diese $(command)
Konstruktion.
Sie erhalten „zu viele Argumente“, weil Ihre Ausdrücke nicht in Anführungszeichen gesetzt sind, sodass die Shell die [number] file
Ausgabe in zwei Wörter statt in nur eins aufteilt.
Im Großen und Ganzen ist es das, was Sie wollen:
test "$(wc -l file|awk '{print $1}')" -eq "$(uniq file|wc -l)"
Wir übergeben wc -l file
die Ausgabe an awk, um nur das erste Feld zu erhalten, das [number]
.
Um die Antwort deutlicher zu machen, sehen Sie sich an, was bei Ihrem ursprünglichen Versuch passiert, indem Sie echo
dem Befehl ein voranstellen:
$ echo test `wc -l file` -eq `uniq file|wc -l`
test 19 file -eq 17
Wie man sehen kann, gibt es 4 Argumente für den test
Befehl: 19
, file
, -eq
und 17
.
Wenn Sie das von mir vorgeschlagene ausprobieren, erhalten Sie einen richtigen Vergleich mit 3 Argumenten für test
:
$ echo test "$(wc -l file|awk '{print $1}')" -eq "$(uniq file|wc -l)"
test 19 -eq 17