Ich beginne damit, dass ich denke, dass dieses Problem etwas weniger unschuldig ist, als es sich anhört.
Was ich tun muss: Suchen Sie nach einem Ordner in der Umgebungsvariablen PATH. Es könnte am Anfang oder irgendwo danach sein. Ich muss nur überprüfen, ob dieser Ordner vorhanden ist.
Beispiel für mein Problem - verwenden wir /opt/gnome
.
SZENARIO 1: Ordner befindet sich nicht am Anfang von PATH
# echo "$PATH"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
# echo "$PATH" | grep ":/opt/gnome"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
Beachten Sie, dass der grep spezifisch genug sein muss, damit er nicht abfängt /var/opt/gnome
. Daher der Doppelpunkt.
SZENARIO 2: Ordner befindet sich am Anfang von PATH.
# echo "$PATH"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
# echo "$PATH" | grep "^/opt/gnome"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
Dies ist mein Problem - ich muss mit diesem Ordner nach einem Doppelpunkt oder einem Zeilenanfang suchen. Was ich tun möchte, ist einer dieser beiden Klammerausdrücke:
# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"
ABER [^
und [:
haben ihre eigenen Bedeutungen. Daher funktionieren die beiden obigen Befehle nicht.
Gibt es eine Möglichkeit, diese beiden Szenarien in einem Befehl zu erfassen?
quelle
/opt/gnome:
oder/opt/gnome$
suchen, werden Sie/opt/gnome-foo
oder finden/opt/gnome/bar
.grep '^\(any number of other matches:*:\)*my match\(:.*\)*$'
Antworten:
Wenn Sie den Inhalt der
PATH
Umgebungsvariablen überprüfen , anstatt nach etwas in einer Datei zu suchen,grep
ist dies das falsche Tool. Es ist einfacher (und schneller und wohl besser lesbar), dies in der Shell zu tun.In bash, ksh und zsh:
Tragbar:
Beachten Sie die Verwendung von
:$PATH:
eher als$PATH
; Auf diese Weise ist die Komponente immer von Doppelpunkten in der Suchzeichenfolge umgeben, selbst wenn sie am Anfang oder Ende von war$PATH
.Wenn Sie eine Zeile einer Datei durchsuchen, können Sie den erweiterten regulären Ausdruck (dh erforderlich
grep -E
) verwenden,(^|:)/opt/gnome($|:)
um eine Übereinstimmung zu erzielen ,/opt/gnome
jedoch nur, wenn er entweder am Anfang einer Zeile oder nach einem Doppelpunkt steht und nur am Ende von die Linie oder gefolgt von einem Doppelpunkt.quelle
Sie können erweiterte reguläre Ausdrücke verwenden, indem Sie einfach verwenden
grep -E
Sie müssen den Anfang und das Ende des Pfads abgleichen, den Sie suchen, um Fehlalarme zu vermeiden.
Entspricht der Instanz am Anfang:
Entspricht auch der Instanz in der Mitte:
Vermeiden von Fehlalarmen:
Keine Übereinstimmungen dort.
Kompakt und elegant. Getestet auf Debian 7.
quelle
egrep
ist deprecated Einsatzgrep -E
(Quelle:man grep
)-w
Option hat einige Probleme. Nur Ziffern, Buchstaben und der Unterstrich gelten als "Wörter". Einige ungewöhnliche, aber mögliche Zeichen lassen es scheitern. Beispielecho '/sbin:/usr/sbin:/var-/opt/gnome' | grep -w "/opt/gnome"
undecho '/sbin:/usr/sbin:/var./opt/gnome' | grep -w "/opt/gnome"
. Diese liefern falsche Ergebnisse./opt/gnome/somethingelse
.echo "/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta" | grep -E "(:|^)/opt/gnome(:|$)"
. Antwort bearbeiten.Wenn Sie nicht verheiratet sind
grep
, können Sieawk
die Datensätze verwenden und trennen:
quelle
Sie könnten auch verwenden
echo "$PATH" | tr ':' '\n' | grep -x "/opt/gnome"
Dadurch wird die Pfadvariable in separate Zeilen aufgeteilt (eine pro Pfad), sodass
grep -x
nach genauen Ergebnissen gesucht werden kann. Dies hat natürlich den Nachteil, dass dafür ein zusätzlicher Prozess erforderlich isttr
. Und es funktioniert nicht, wenn einPATH
Ordnername in Zeilenumbruchzeichen enthält.quelle
Ich weiß nicht, ob es für eine Antwort ausreicht, aber
wird Ihr Bedürfnis befriedigen.
aber
quelle
/
es kein Teil des Wortes ist, sondernr
ist./opt/gnome-beta
,/home/bob/opt/gnome
, ...grep -w /usr/local -o <<< /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
------/usr/local /usr/local /usr/local
So wählen Sie
/opt/gnome
von Nicht-Wort - Zeichen umgeben (neue Linien,:
,/
etc) , versuchen Sie dieses:quelle
Sie können dies zuverlässig und mit geringem Aufwand tun
grep
. Sie können Erweiterungen nutzen, die weit verbreitet sind und von denen bereits viele Lösungen angeboten wurden, aber selbst mit Basis-Regex ist dies einfach, obwohl dies auf den ersten Blick möglicherweise nicht intuitiv möglich ist.Mit Basic Regex - und so mit
grep
- haben Sie immer zwei zuverlässige Anker - den Kopf und das Ende der Linie. Sie können eine Übereinstimmung an beiden verankern, unabhängig von ihrer Position auf der Linie :grep
Es werden vom Kopf der Zeile so viele Vorkommen der\(grouped\)
Unterausdrücke abgeglichen, wie erforderlich sind, um als nächstes auf Ihr Trennzeichen und dann auf Ihre explizite Übereinstimmung zu treffen , und vom Ende Ihrer Übereinstimmung bis zum Ende der Zeile auf dieselbe Weise. Wenn Ihre explizite Übereinstimmung nicht explizit übereinstimmt, schlägt sie fehl und gibt nichts aus.Und so könnten Sie zum Beispiel tun:
Überzeugen Sie sich selbst:
AUSGABE
quelle
Sie haben einen Randfall bemerkt ... Sie könnten ihn vermeiden, indem Sie die Erscheinung eines: am Anfang der Zeile erzwingen:
oder wenn der Pfad genau ist, fügen Sie am Ende auch einen hinzu, um sicherzustellen, dass er begrenzt ist:
quelle