Als Teil dieses Skripts muss ich überprüfen können, ob das erste angegebene Argument mit dem ersten Wort der Datei übereinstimmt. Wenn dies der Fall ist, beenden Sie das Programm mit einer Fehlermeldung. Wenn dies nicht der Fall ist, hängen Sie die Argumente an die Datei an. Ich verstehe, wie man die if
Anweisung schreibt , aber nicht, wie man sie grep
in einem Skript verwendet. Ich verstehe, das grep
wird ungefähr so aussehen
grep ^$1 schemas.txt
Ich denke, das sollte viel einfacher sein, als ich es mache.
Ich erhalte die Fehlermeldung "zu viele Argumente" if
. Ich habe den Zwischenraum entfernt grep -q
und dann einen fehlerhaften Binäroperator erwartet bekommen.
if [ grep -q ^$1 schemas.txt ]
then
echo "Schema already exists. Please try again"
exit 1
else
echo "$@" >> schemas.txt
fi
[
...]
und es wird funktionieren. Obwohl Sie wahrscheinlich Ihr Muster zitieren möchten:if grep -q "^$1" schemas.txt; then …
Antworten:
grep
Gibt einen anderen Exit-Code zurück, wenn etwas (Null) gefunden wurde, oder wenn nichts gefunden wurde (nicht Null). In einerif
Anweisung wird ein Exit-Code ungleich Null auf "true" und ein Exit-Code ungleich Null auf "false" abgebildet. Außerdem hat grep ein-q
Argument, um den übereinstimmenden Text nicht auszugeben (sondern nur den Exit-Statuscode zurückzugeben).So können Sie grep wie folgt verwenden:
Kurz gesagt , wenn Sie so etwas tun
if [ -z "$var" ]…
, stellt sich heraus, dass[
es sich tatsächlich um einen Befehl handelt, den Sie ausführen , genau wie grep. Auf meinem System ist es/usr/bin/[
. (Nun, technisch gesehen hat Ihre Shell es wahrscheinlich eingebaut, aber das ist eine Optimierung. Es verhält sich so, als wäre es ein Befehl). Es funktioniert auf die gleiche Weise und[
gibt einen Null-Exit-Code für true und einen Nicht-Null-Exit-Code für false zurück. (test
ist dasselbe wie[
, bis auf das Schließen]
)quelle
ls -l /usr/bin/\[
und umman [
zu sehen, dass[
es sich um ein Programm wie jedes andere handelt, sieht es einfach wie ein syntaktisches Element aus - dies sollte es klar und verständlich machen. (Der Einfachheit halber[
ist es auch in Bash, Dash und andere integriert - aber es ist immer noch ein Befehl). versuche es auchtype -all [
in bash.-q
Option weg, die grep anweist , leise zu sein (die übereinstimmenden Zeilen nicht zu drucken).Eine andere einfache Möglichkeit ist die Verwendung
grep -c
.Dieser gibt (nicht als Exit-Code zurück) die Anzahl der Zeilen aus, die mit dem Muster übereinstimmen, also 0, wenn keine Übereinstimmung vorliegt, oder 1 oder mehr, wenn eine Übereinstimmung vorliegt.
Wenn Sie also überprüfen möchten, ob das Muster dreimal oder öfter übereinstimmt, tun Sie Folgendes:
quelle
grep -cim1
stattdessen, um 1 unabhängig von der Anzahl der gefundenen Übereinstimmungen auszugeben .Ich weiß, dass ich zu spät dafür bin, aber ich liebe diese kurze Version:
quelle
Wenn wir das erste Wort einer Datei abfangen wollen, müssen wir
-zw
grep hinzufügenOhne
-z
bekommen wir das erste Wort einer Zeile. Ohne-w
bekommen wir teilweise Worte.quelle
Wenn Sie es mit eckigen Klammern verwenden möchten, können Sie Folgendes ausführen
Diese Logik funktioniert für alle Befehle. Platzieren Sie Ihre Befehle einfach im Backtick (die Schaltfläche über der Registerkarte oder nach unten auf der Esc-Schaltfläche oder links auf der 1-Schaltfläche).
quelle
`grep -q PATTERN file.txt`
, andernfalls wird der Operator split + glob angewendet, und dies würde Probleme bei jeder Ausgabe verursachen, die Zeichen$IFS
oder Platzhalterzeichen enthält . Im Allgemeinen[ "`cmd`" ]
würde true zurückgegeben, wenncmd
mindestens eine nicht leere Zeile auf stdout ausgegeben wird (mit potenziellen Problemen, wenn NUL-Bytes ausgegeben werden). Das heißt, die Shell muss die gesamte Ausgabe im Speicher ablegen und warten, bis sie beendet ist. Die Verwendung vonif cmd | grep -q .
stattdessen kann in dieser Hinsicht vorzuziehen sein.-q
Schalters ist die Unterdrückunggrep
der Ausgabe. Sie sagen: Suchen Sie nach PATTERN in der Datei file.txt, unterdrücken Sie alle Ausgaben und setzen Sie den Rückgabestatus entsprechend, ob PATTERN gefunden wurde. Dann ignorieren den Rückgabestatus, nehmen Sie die Befehlsausgabe (die wir leer sein gezwungen), einzelne Wörter aufgespalten und Datei glob Expansion gelten (was ohne Argumente überhaupt), dann führen Sie den[
(akatest
) Befehl mit genau einem Argument - nämlich ,]
- und dann, da dies zu einem Fehler führt, "nicht gefunden". @ StéphaneChazelas, habe ich etwas verpasst?-q
. Dieser Kommentar hätte Sinn ergeben[ `grep PATTERN file.txt ` ]
, wäre aber, wie im Kommentar angedeutet,[ "`grep -n PATTERN file.txt`" ]
besser, wenn PATTERN nur mit leeren Zeilen übereinstimmt. Obwohlif grep -q PATTERN file.txt
du es hier natürlich willst.