Dmitry Nikolaev - stock.adobe.co
Wichtige Alternativen zu PowerShell grep
Mithilfe von grep können Dateien und Ausgaben in PowerShell durchsucht werden. Allerdings gibt es noch andere Cmdlets, die Sie für solche Aufgaben nutzen können.
Um im Terminal von PowerShell nach Informationen zu suchen, nutzen Sie das Dienstprogramm grep. Im Kontext von PowerShell sind die Begriffe grep und suchen mittlerweile sogar synonym zu verwenden.
Das Cmdlet Select-String von PowerShell ist zwar nicht ganz so bekannt, bietet aber weitgehend die gleichen Funktionen wie grep. Dabei ist es leistungsfähig genug, um die häufigsten Anforderungen zu erfüllen. Beide sind unglaublich nützliche Tools. Um zu entscheiden, welches für Sie das Richtige ist, sollten Sie die Grundlagen der Verwendung beider Optionen kennenlernen und anhand der Beispiele in diesem Artikel vergleichen.
Windows und Linux im Vergleich: Die Verwendung von grep und Select-String
Der größte Unterschied zwischen grep und Select-String besteht darin, dass ersteres ursprünglich für Unix entwickelt wurde, während letzteres in PowerShell integriert ist.
Aber machen Sie sich keine Sorgen, dass Sie die Verwendung eines speziellen Tools für das Betriebssystem Ihrer Wahl lernen müssen – grep und Select-String sind sowohl unter Windows als auch unter Linux verfügbar. Dazu müssen Sie PowerShell unter Linux ausführen oder ein Windows Subsystem für Linux (WSL) auf Windows einrichten. Alle in dieser Anleitung gezeigten Bash Screenshots stammen von einer Ubuntu-WSL-Instanz.
Hilfe für grep und Select-String
Wann immer Sie ein neues Tool verwenden möchten, sollten Sie die Hilfedokumentation lesen. Das funktioniert in beiden Fällen wie gewohnt für PowerShell-Dienstprogramme und -Cmdlets.
Für grep verwenden Sie den Befehl --help.
grep --help
Für Select-String rufen Sie das Hilfesystem von PowerShell mit dem folgenden Code auf:
help Select-String
In diesem Artikel behandeln wir zwar nicht die gesamte Dokumentation für PowerShell oder grep, aber wenn Sie wissen, wie Sie diese Ressourcen finden, können Sie Probleme beheben und zukünftige Fragen beantworten.
Grundlagen der grep- und Select-String-Syntax
Sowohl grep als auch Select-String sind darauf ausgelegt, nach Dateien und Zeichenketten zu suchen. Und sowohl Bash als auch PowerShell verwenden Piping, sodass es sogar möglich ist, beide zum Durchsuchen von Befehlsausgaben zu verwenden.
Da Sie mit diesen Tools die Ausgabe jedes anderen Befehls oder jeder ausführbaren Befehlszeile durchsuchen können, müssen Sie den Unterschied zwischen Pipes in Bash – oder der Linux-Shell Ihrer Wahl – und der PowerShell verstehen. Bash übergibt nämlich Zeichenketten, während PowerShell Objekte übergibt, was bedeutet, dass Sie viele grep-Funktionen in PowerShell mit dem Cmdlet Where-Object umsetzen.
Die Zeichenkettensuche von grep und PowerShell-Cmdlets im Vergleich
Als nächstes wollen wir einige Beispiele für verschiedene Arten von Suchen mit grep und Select-String von PowerShell zeigen.
Eine Zeichenfolge nach einer anderen durchsuchen
Angenommen, Sie möchten ein bestimmtes Wort in einer Zeichenfolge finden. Der folgende Code und die Ausgabe zeigen ein Beispiel dafür, wie das mit grep möglich ist.
echo ‘Say that we have a string and we want to find a specific word in that string’ | grep ‘string’
Und hier sehen Sie, wie Sie die gleiche Suche mit Select-String durchführen:
‘Say that we have a string and we want to find a specific word in that string’ | Select-String ‘string’
Dieses Beispiel verdeutlicht einige Unterschiede zwischen PowerShell und grep. Erstens hebt grep standardmäßig alle Übereinstimmungen hervor, während das bei Select-String nicht der Fall ist. Um das gleiche Feature in Select-String zu verwenden, fügen Sie den Parameter -AllMatches hinzu.
Die bereits erwähnten Unterschiede in der Art und Weise, wie die Daten in den beiden Shells über die Pipeline geleitet werden, sind hier ebenfalls zu sehen. In der Bash müssen Sie die Zeichenfolge über die Pipeline weiterleiten, indem Sie sie mit echo ausgeben, während PowerShell standardmäßig die einfache Zeichenfolge in die Pipeline ausgibt.
Eine Datei nach einer Zeichenfolge durchsuchen
Dateien sind nur Zeichenketten oder Arrays von Zeichenketten, die auf der Festplatte gespeichert sind. Sowohl PowerShell als auch grep machen das Durchsuchen von Dateien so einfach wie das Durchsuchen von Zeichenketten.
Verwenden Sie zum Beispiel den folgenden grep-Befehl, um eine Skriptdatei nach allen Instanzen der Zeichenfolge if zu durchsuchen.
grep if./chkrootkit
Um die gleiche Suche mit Select-String durchzuführen, führen Sie den folgenden Code aus:
Select-String ‘if‘.\chkrootkit
Beachten Sie, dass Select-String standardmäßig die Zeilennummer zu jeder Übereinstimmung hinzufügt, während grep das nicht tut. Um Zeilennummern in grep hinzuzufügen, verwenden Sie den Parameter -n.
Durchsuchen einer Befehlsausgabe nach einer Zeichenkette
Ein weiterer Anwendungsfall für beide Werkzeuge ist das Parsen von Befehlsausgaben, um das Vorkommen einer Zeichenkette zu ermitteln. Aufgrund der unterschiedlichen Handhabung von Piping in Bash und PowerShell ist das PowerShell-grep-Äquivalent hier jedoch nicht immer Select-String.
Im folgenden Bash-Beispiel analysieren wir die Ausgabe des netstat-Befehls hinsichtlich einer bestimmten IP-Adresse mit grep.
netstat | grep 172.30.334.184
In PowerShell verwenden Sie Select-String, um die gleiche Aufgabe auszuführen.
netstat | Select-String 10.0.0.114
Alternativ erzielen Sie die gleichen Ergebnisse mit Where-Object, einem anderen PowerShell-Cmdlet, das dem Filtern von Objekten dient. Da Powershell Objekte statt Zeichenfolgen an die Pipeline sendet, kann das Cmdlet Where-Object Befehlsaufgaben parsen.
Get-NetTCPConnection | ?{US-Dollar_.LocalAddress -eq '10.0.0.114'}
Wenn Sie die grep-Suchmethode bevorzugen, aber PowerShell verwenden, können Sie die Cmdlet-Ausgabe über die Pipeline an Out-String übergeben, um die Ausgabe als Zeichenfolge zu durchsuchen.
Get-NetTCPConnection | Out-String -Stream | Select-String '10.0.0.114'
Der Parameter -Stream im obigen Beispiel fügt jeder Zeile einen Zeilenumbruch hinzu, wodurch die Ausgabe auf Zeilen mit Übereinstimmungen beschränkt wird.
grep und Select-String: Das Schreiben regulärer Ausdrücke
Sowohl grep als auch Select-String von PowerShell unterstützen die Suche mit regulären Ausdrücken. Da die beiden jedoch unterschiedliche Engines verwenden, unterscheiden sich ihre Regeln zum Erstellen regulärer Ausdrücke.
Nehmen wir einmal an, Sie möchten nach einer Telefonnummer suchen, ohne diese Telefonnummer genau zu kennen. Wenn Sie mit PowerShell besser vertraut sind, könnten Sie einen einfachen regulären Ausdruck wie den folgenden schreiben, um Vorkommen von Telefonnummern zu erfassen.
\d{3}-\d{3}-\d{4}
Dieser Ausdruck basiert auf der Zeichenklasse \d, die in grep nicht funktioniert, es sei denn, Sie verwenden die Perl-Engine. Fügen Sie dazu beim Aufruf von grep den Parameter -P hinzu.
echo "My phone number is: 123-456-7890, call me" | grep -P "\d{3}-\d{3}-\d{4}"
Um nur die regulären Standardausdrücke von grep und nicht die Perl-Engine zu verwenden, verwenden Sie stattdessen eine benutzerdefinierte Zeichenklasse, die auf Zahlen passt.
echo "My phone number is: 123-456-7890, call me" | grep "[0-9]\{3\}-[0-9]\{3\}-[0-9]\{4\}"
Im folgenden PowerShell-Beispiel wird mit dem im ersten grep-Beispiel verwendeten regulären Ausdruck nach derselben Zeichenfolge gesucht.
"My phone number is: 123-456-7890, call me" | Select-String "\d{3}-\d{3}-\d{4}"
Diese Beispiele zeigen einen wichtigen Unterschied zwischen PowerShell und grep beim Schreiben regulärer Ausdrücke: grep kann auf mehrere Engines zugreifen, während PowerShell ausschließlich auf .NET-Engine für reguläre Ausdrücke angewiesen ist. Folglich ist PowerShell konsistenter, verfügt aber nicht über die Flexibilität von grep.
grep und PowerShell: Durchsuchen von Dateien
Einer der Vorteile von grep gegenüber Select-String beim Durchsuchen von Dateien ist seine Fähigkeit, rekursiv zu suchen, ohne andere Tools zu verwenden.
Der folgende grep-Befehl durchsucht beispielsweise rekursiv den Bash-Skriptordner, um alle Dateien zu finden, die die Zeichenfolge #!/bin/sh enthalten.
grep -r --include \*.sh '#!/bin/sh' *
In PowerShell besteht derselbe Prozess aus mehreren Schritten. Verwenden Sie zunächst das Cmdlet Get-ChildItem, um die Dateien rekursiv zu durchsuchen, und leiten Sie dann die Ausgabe über die Pipeline mit Select-String an das Cmdlet ForEach-Object weiter.
Get-ChildItem *.sh -Recurse | ForEach-Object { Select-String '#\!\/bin\/sh' -Path US-Dollar_.FullName }
Die Muster, die Sie für die Suche nach Dateien verwenden, sind für jedes Tool unterschiedlich, was wiederum auf die Unterschiede zwischen den Engines für reguläre Ausdrücke zurückzuführen ist.
Ein weiterer Unterschied ist, dass grep standardmäßig keine Zeilennummern enthält, während Select-String das tut. Wie bereits erwähnt, können Sie den Parameter -n verwenden, um Zeilennummern zur grep-Ausgabe hinzuzufügen.
grep -n -r --include \*.sh '#!/bin/sh' *