Jednym z pierwszych poleceń Linuksa, którego uczy się wielu administratorów systemu, jest grep. To czcigodne narzędzie istnieje od dziesięcioleci i jest niezbędne w zestawie narzędzi każdego administratora. Rdzeniem grepa jest po prostu zdolność do przeszukiwania czystego tekstu w poszukiwaniu wzorca RegEx. Grep może przeszukiwać pliki w podanym katalogu lub strumieniowe dane wejściowe w celu uzyskania dopasowań. Czy wiesz, że PowerShell posiada grepa? No cóż…prawie.
PowerShell, będąc językiem, jest czymś więcej niż tylko binarnym programem jednego przeznaczenia. W związku z tym, jakie wbudowane możliwości istnieją, aby wyszukiwać zwykły tekst używając wzorców RegEx, tak jak robi to grep? W tym artykule poznamy niezliczone sposoby wyszukiwania tekstu w plikach za pomocą PowerShella.
Poznanie polecenia Select-String
Select-String
(nasz PowerShellowy grep) działa na liniach tekstu i domyślnie szuka pierwszego dopasowania w każdej linii, a następnie wyświetla nazwę pliku, numer linii i tekst w dopasowanej linii. Dodatkowo, Select-String
może pracować z różnymi kodowaniami plików, takimi jak tekst Unicode, poprzez użycie znaku kolejności bajtów (BOM) do określenia formatu kodowania. Jeśli brakuje BOM, Select-String
przyjmie, że jest to plik UTF8.
Parametry Select-String
-
AllMatches
– Normalnie,Select-String
będzie szukał tylko pierwszego dopasowania w każdej linii, używając tego parametru cmdlet będzie szukał więcej niż jednego dopasowania. Pojedynczy obiektMatchInfo
nadal będzie emitowany dla każdej linii, ale będzie zawierał wszystkie znalezione dopasowania. -
CaseSensitive
– Domyślnie wielkość liter nie jest rozróżniana, zmusza to cmdlet do szukania dopasowań, które pasują dokładnie do wzorca wejściowego. -
Context
– Bardzo przydatny parametr w tym, że można określić liczbę linii przed i po dopasowaniu, które będą wyświetlane. Dodanie tego parametru modyfikuje emitowany obiektMatchInfo
tak, aby zawierał nową właściwośćContext
, która zawiera określoną liczbę linii.
Pamiętaj, że jeśli potokujesz dane wyjściowe
Select-String
do innego wywołaniaSelect-String
, kontekst nie będzie dostępny, ponieważ wyszukujesz tylko na pojedynczej wynikowejMatchInfo
line
właściwości.
-
Culture
– Używany z parametremSimpleMatch
, określa kulturę, która ma być dopasowana do podanego wzorca. Obejmuje to takie opcje jaken-US
es
, lubfr-FR
jako przykłady. Kilka innych przydatnych opcji toOrdinal
iInvariant
Ordinal
jest dla niejęzykowych porównań binarnych, aInvariant
jest dla porównań niezależnych od kultury.
Ten parametr został wprowadzony w PowerShell 7 i nie jest dostępny dla wcześniejszych wersji. Należy również pamiętać, że domyślnie będzie on używał bieżącej kultury systemu, którą można znaleźć za pomocą
Get-Culture
.
-
Encoding
– Określa kodowanie pliku docelowego do przeszukiwania, które domyślnie wynosiutf8NoBOM
.-
ascii
: Stosuje kodowanie dla zestawu znaków ASCII (7-bitowe). -
bigendianunicode
: Koduje w formacie UTF-16 z zastosowaniem kolejności bajtów big-endian. -
oem
: Używa domyślnego kodowania dla MS-DOS i programów konsolowych. -
unicode
: Koduje w formacie UTF-16 używając little-endian byte order. -
utf7
: Koduje w formacie UTF-7. -
utf8
: Koduje w formacie UTF-8. -
utf8BOM
: Koduje w formacie UTF-8 z oznaczeniem kolejności bajtów (BOM) -
utf8NoBOM
: Koduje w formacie UTF-8 bez oznaczenia kolejności bajtów (BOM) -
utf32
: Koduje w formacie UTF-32.
Począwszy od wersji PowerShell Core 6.2, parametr
Encoding
akceptuje również numeryczne identyfikatory zarejestrowanych stron kodowych, takie jak1251
lub nazwy łańcuchowe, takie jakwindows-1251
. -
Począwszy od PowerShell Core 6.2, parametr
Encoding
przyjmuje również numeryczne identyfikatory zarejestrowanych stron kodowych, takie jak1251
lub nazwy łańcuchowe, takie jakwindows-1251
.
-
Exclude
– Pracując z parametremPath
, wykluczaj konkretne elementy za pomocą wzorca, np.*.txt
. -
Include
– Podobnie jak w przypadku parametruExclude
Include
będzie zawierał tylko określone elementy przy użyciu wzorca, takiego jak*.log
. -
List
– Zwraca tylko pierwszą instancję pasującego tekstu z każdego pliku wejściowego. Ma to być szybki i wydajny sposób na pobranie listy plików, które mają pasującą zawartość. -
LiteralPath
– To mówiSelect-String
, aby użyć wartości jako danych wejściowych, zamiast interpretować wartości takie jak*
jako symbol wieloznaczny. Jeśli ścieżka zawiera znaki ucieczki, umieść je w pojedynczych cudzysłowach, aby nie dokonywać interpretacji. -
NoEmphasis
– Zamiast podświetlania łańcucha, do którego dopasowany jest wzorzec, wyłącz podświetlanie dopasowań. Domyślnie, podkreślenie używa negatywnych kolorów opartych na kolorach tła tekstu. -
NotMatch
– Wyszukaj tekst, który nie pasuje do podanego wzorca. -
Path
– Określ ścieżkę do plików do przeszukania. Dozwolone są symbole wieloznaczne, ale nie można określić tylko katalogu. Domyślnie jest to katalog lokalny. -
Pattern
– Wzorzec do przeszukiwania zawartości wejściowej lub plików w oparciu o RegEx. -
SimpleMatch
– Użyj prostego dopasowania zamiast wyrażeń regularnych. Ponieważ RegEx nie jest używany, zwrócony obiektMatchInfo
nie posiada żadnych wartości we właściwościachMatches
. -
Raw
– Wyprowadzenie pasujących łańcuchów, bez obiektuMatchInfo
. Jest to zachowanie, które jest najbardziej podobne dogrep
, a nie do bardziej obiektowej natury PowerShell. -
Quiet
– Zwraca tylko$true
lub$false
jeśli wzorzec został znaleziony.
Używanie PowerShell Grep err… Select-String
Oczywiście wiedza o tym jak działają parametry i opcje cmdleta nie jest tym samym co używanie go w środowisku produkcyjnym. Zanurzmy się w przykładach i zobaczmy jak możemy wykorzystać Select-String
do ułatwienia wyszukiwania dopasowań tekstowych.
Istnieją trzy sposoby, na które możemy użyć Select-String
do znalezienia dopasowań.
- Pipe in quoted text to the
Select-String
cmdlet, i.e. stream in the text. - Korzystając z tekstu przechowywanego w zmiennej, przekaż zmienną do parametru
InputObject
. - Użyj parametru
Path
, aby określić pliki, w których należy szukać tekstu.
Pliki, których używamy do testowania to losowo generowana zawartość, ale tego samego typu, jaki często można znaleźć w systemach produkcyjnych.
Proste dopasowanie w plikach
Zaczynając od bardzo prostego przykładu, poszukajmy Joe
w garści plików CSV.
Select-String -Path "Users\*.csv" -Pattern "Joe"
Jak widać, jest to dość proste, widzimy jak Joe
jest podświetlony w linii z resztą danych. Ale jakie dane są tutaj faktycznie zwracane? Przyjrzyjmy się wszystkim właściwościom zwróconego dopasowania.
Select-String -Path "Users\*.csv" -Pattern "Joe" | Select-Object * -First 1
Mamy tutaj kilka właściwości, które są przydatne. Zwłaszcza line
path
pattern
, oraz matches
. Większość tego, co chcemy wiedzieć, znajduje się we właściwości matches
.
Select-String -Path "Users\*.csv" -Pattern "Joe" | Select-Object -ExpandProperty Matches -First 1
Widać tutaj, że mimo iż użyliśmy prostego wyrażenia, to nadal jest to wyrażenie RegEx i dostępne są kolejne szczegóły.
A co jeśli szukamy kilku różnych wartości używając wzorców oddzielonych przecinkami? Jest to użyteczne, ponieważ w rzeczywistości definiuje to trzy różne wzorce, a nie jedną złożoną wartość RegEx.
Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry"
Możesz zobaczyć jak to jest w tym przypadku, jeśli wybierzemy tylko filename
pattern
, oraz line
z naszego wyszukiwania.
Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry" | Select-Object FileName, Pattern, Line
Złożone dopasowywanie RegEx
Jak już zademonstrowaliśmy kilka prostszych metod dopasowywania, co z wykorzystaniem RegEx do szukania bardziej użytecznych wzorców? Trzy przykłady tutaj to szukanie adresów e-mail, adresów IP i numerów ubezpieczenia społecznego (SSN). Użyte tutaj wzorce nie są jedynym sposobem na skonstruowanie wyszukiwania RegEx, mogą istnieć prostsze sposoby. PowerShell Grep (Select-String) jest dość zaawansowanym cmdletem.
Sprawdźmy, czy w naszych plikach znajdują się e-maile. Użycie nieco skomplikowanego dopasowania RegEx, jak pokazano poniżej, zademonstruje znalezienie tych dopasowań.
Select-String -Path "Users\*.csv" -Pattern '\\b+\.{2,4}\b' | Select-Object -First 10
Oczywiście, większym problemem może być to, że w pliku znajdują się numery SSN. Bardzo proste dopasowanie do tego byłoby następujące.
Select-String -Path "Users\*.csv" -Pattern '\d\d\d-\d\d-\d\d\d\d' | Select-Object -First 10
Na koniec, co jeśli chcielibyśmy wyszukać kilka adresów IP w naszym pliku? Użycie innego wyrażenia RegEx do wyszukania tego wzorca, sprawi, że praca będzie szybka.
Select-String -Path "Users\*.csv" -Pattern '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' | Select-Object -First 10
Zastrzeżenie dotyczące tego RegEx. Technicznie rzecz biorąc, będzie on pasował do wartości aż do 999.999.999.999
, który jest nieprawidłowym IP. Możesz skonstruować dokładniejsze wyrażenia RegEx, które będą dłuższe, ale jest to kompromis w zależności od tego, co chcesz zrobić.
Szukanie z kontekstem
Kontekst jest bardzo przydatny w rozwiązywaniu problemów, pomaga wyjaśnić, co dzieje się przed wystąpieniem zdarzenia i po nim. Na przykład, poszukajmy w logu Apache’a i znajdźmy ten suspendedpage.cgi
tekst.
Select-String -Path "Web\*.txt" -Pattern "suspendedpage.cgi" -Context 1 | Select-Object -First 1
Prosta >
wskazuje na dopasowaną linię i istnieje jedna linia przed i po dopasowaniu. W tym przykładzie, to może nam powiedzieć, że bot Google szukał robots.txt
i niestety otrzymał suspendedpage.cgi
wynik zamiast. Następnie spróbował wejść na stronę główną i być może otrzymał ten sam błąd.
Co dokładnie zawiera właściwość context
emitowana przez obiekt MatchInfo
? Jeśli rozwiniemy tę właściwość, można zobaczyć, że istnieje PreContent
i PostContent
. Oznacza to, że możesz manipulować tym w dalszej części linii, jeśli zajdzie taka potrzeba.
Select-String -Path "Web\*.txt" -Pattern "suspendedpage.cgi" -Context 1 | Select-Object -ExpandProperty Context -First 1 | Format-List
Inne przykłady przeszukiwania plików dziennika znajdują się w artykułach takich jak Making Sense of the Microsoft DNS Debug Log, który demonstruje użycie Select-String
do przeglądania dziennika debugowania DNS. PowerShell grep jest silny w tym poście.
Wnioski
Grep jest niesamowicie użytecznym narzędziem w świecie Linuksa, a Select-String
oferuje wiele z tej samej funkcjonalności w świecie PowerShell. Dodanie obiektowej natury PowerShella tylko zwiększa użyteczność i przydatność tego polecenia.
Dla wielu administratorów systemów, możliwość szybkiego i efektywnego przeszukiwania plików logów różnych typów, wraz ze zrozumieniem kontekstu, jest niezwykle ważną i niezbędną umiejętnością. PowerShell Select-String
ułatwia to zadanie i pozwala zaoszczędzić niezliczone godziny rozwiązywania problemów!