Polecenie FINDSTR w systemie Windows jest strasznie udokumentowane. Dostępna jest bardzo prosta pomoc z wiersza poleceń FINDSTR /?
, lub HELP FINDSTR
, ale jest ona wyjątkowo nieodpowiednia. Jest trochę więcej dokumentacji online na https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr .
Istnieje wiele funkcji i ograniczeń FINDSTR, o których nawet nie wspomina się w dokumentacji. Nie można ich również przewidzieć bez wcześniejszej wiedzy i / lub starannych eksperymentów.
Pytanie brzmi: jakie są nieudokumentowane funkcje i ograniczenia FINDSTR?
Celem tego pytania jest zapewnienie kompleksowego repozytorium wielu nieudokumentowanych funkcji, aby:
A) Programiści mogą w pełni korzystać z dostępnych tam funkcji.
B) Deweloperzy nie marnują czasu na zastanawianie się, dlaczego coś nie działa, gdy wydaje się, że powinno.
Przed udzieleniem odpowiedzi upewnij się, że znasz istniejącą dokumentację. Jeśli informacje są objęte pomocą, to nie należy tutaj.
Nie jest to również miejsce do pokazania interesujących zastosowań FINDSTR. Jeśli osoba logiczna mogłaby przewidzieć zachowanie określonego użycia FINDSTR na podstawie dokumentacji, nie należy tutaj.
W ten sam sposób, jeśli osoba logiczna mogłaby przewidzieć zachowanie określonego użycia na podstawie informacji zawartych w jakichkolwiek istniejących odpowiedziach, to znowu nie należy tutaj.
źródło
grep
co jest bardzo dobrze zrozumiane i udokumentowane :-) Zobacz na przykład stackoverflow.com/questions/2635740/… .Odpowiedzi:
Przedmowa
Wiele informacji zawartych w tej odpowiedzi zostało zebranych na podstawie eksperymentów przeprowadzonych na komputerze z systemem Vista. O ile wyraźnie nie zaznaczono inaczej, nie potwierdziłem, czy informacje dotyczą innych wersji systemu Windows.
Dane wyjściowe FINDSTR
Dokumentacja nigdy nie zadaje sobie trudu, aby wyjaśnić dane wyjściowe FINDSTR. Wskazuje to na to, że drukowane są pasujące linie, ale nic więcej.
Format dopasowanego wyjścia liniowego jest następujący:
filename: lineNumber: lineOffset: text
gdzie
fileName: = nazwa pliku zawierającego pasującą linię. Nazwa pliku nie jest drukowana, jeśli żądanie dotyczyło jednoznacznie pojedynczego pliku lub podczas wyszukiwania danych wejściowych w trybie potokowym lub danych przekierowanych. Po wydrukowaniu nazwa pliku zawsze będzie zawierać wszelkie podane informacje o ścieżce. Dodatkowe informacje o ścieżce zostaną dodane, jeśli
/S
zostanie użyta opcja. Ścieżka drukowana jest zawsze względna do podanej ścieżki lub względna do bieżącego katalogu, jeśli nie została podana.Uwaga - Podczas wyszukiwania wielu plików można uniknąć prefiksu nazwy pliku, używając niestandardowych (i słabo udokumentowanych) symboli wieloznacznych
<
i>
. Dokładne zasady działania tych symboli wieloznacznych można znaleźć tutaj . Na koniec możesz spojrzeć na ten przykład, w jaki sposób niestandardowe symbole wieloznaczne działają z FINDSTR .lineNumber: = Numer linii pasującego wiersza reprezentowany jako wartość dziesiętna, gdzie 1 oznacza pierwszy wiersz danych wejściowych. Drukowane tylko, jeśli
/N
podano opcję.lineOffset: = Przesunięcie dziesiętnego bajtu na początku pasującej linii, przy czym 0 oznacza 1. znak 1. linii. Drukowane tylko, jeśli
/O
podano opcję. To nie jestprzesunięcie dopasowania w linii. Jest to liczba bajtów od początku pliku do początku linii.text = Binarna reprezentacja pasującej linii, łącznie z dowolnymi <CR> i / lub <LF>. Nic nie pozostaje poza wyjściem binarnym, tak że ten przykład, który pasuje do wszystkich wierszy, utworzy dokładną kopię binarną oryginalnego pliku.
Opcja / A ustawia kolor fileName :, lineNumber :, i lineOffset: tylko dane wyjściowe. Tekst pasującej linii jest zawsze wyprowadzany z bieżącym kolorem konsoli. Opcja / A działa tylko wtedy, gdy dane wyjściowe są wyświetlane bezpośrednio na konsoli. Opcja / A nie ma wpływu, jeśli dane wyjściowe zostaną przekierowane do pliku lub potoku. Zobacz edycję 2018-08-18 w odpowiedzi Aacini, aby uzyskać opis błędnego zachowania po przekierowaniu danych wyjściowych do CON.
Większość znaków kontrolnych i wiele rozszerzonych znaków ASCII jest wyświetlanych jako kropki na XP.
FINDSTR na XP wyświetla większość niedrukowalnych znaków kontrolnych z pasujących linii jako kropki (kropki) na ekranie. Następujące znaki kontrolne są wyjątkami; wyświetlają się one same: 0x09 Tab, 0x0A LineFeed, 0x0B Tab pionowy, 0x0C Form Feed, 0x0D Powóz powrotny.
XP FINDSTR przekształca również wiele rozszerzonych znaków ASCII w kropki. Rozszerzone znaki ASCII wyświetlane w XP jako kropki są takie same, jak znaki przekształcane po dostarczeniu z wiersza poleceń. Zobacz sekcję „Limity znaków dla parametrów wiersza poleceń - Rozszerzona transformacja ASCII” , w dalszej części tego postu
Znaki kontrolne i rozszerzone ASCII nie są konwertowane na kropki w XP, jeśli dane wyjściowe są przesyłane potokowo, przekierowywane do pliku lub w ramach klauzuli FOR IN ().
Vista i Windows 7 zawsze wyświetlają wszystkie znaki jako siebie, nigdy jako kropki.
Kody zwrotne (ERRORLEVEL)
/A:xx
opcję/L
i/R
oba określone/A:
,/F:
,/C:
,/D:
, lub/G:
/F:file
lub/G:file
nie został znalezionypatrz Limit terminów klas znaków Regex i BŁĄD w części 2 odpowiedzi
Źródło danych do wyszukiwania (zaktualizowane na podstawie testów w systemie Windows 7)
Findstr może wyszukiwać dane tylko z jednego z następujących źródeł:
nazwy plików określone jako argumenty i / lub za pomocą
/F:file
opcji.standardowe poprzez przekierowanie
findstr "searchString" <file
strumień danych z potoku
type file | findstr "searchString"
Argumenty / opcje mają pierwszeństwo przed przekierowaniem, które ma pierwszeństwo przed przesyłanymi danymi.
Argumenty nazwy pliku i
/F:file
można je łączyć. Można użyć wielu argumentów nazwy pliku. Jeśli/F:file
podano wiele opcji, używana jest tylko ostatnia. Symbole wieloznaczne są dozwolone w argumentach nazw plików, ale nie w obrębie pliku wskazywanego przez/F:file
.Źródło ciągów wyszukiwania (zaktualizowane na podstawie testów z Windows 7) i opcje mogą być łączone. Można podać wiele opcji. Jeśli podano wiele opcji, używana jest tylko ostatnia. Jeśli użyty jest albo lub, zakłada się, że wszystkie argumenty nie będące opcjami są plikami do przeszukania. Jeśli ani nie zostanie użyty, ani pierwszy argument nie będący opcją jest traktowany jako lista rozdzielonych spacjami haseł.
/G:file
/C:string
/C:string
/G:file
/G:file
/C:string
/G:file
/C:string
Podczas korzystania z
/F:FILE
opcji nazwy plików nie mogą być cytowane w pliku .Nazwy plików mogą zawierać spacje i inne znaki specjalne. Większość poleceń wymaga cytowania takich nazw plików. Ale
/F:files.txt
opcja FINDSTR wymaga, aby nazwy plików w plikach.txt NIE były cytowane. Plik nie zostanie znaleziony, jeśli nazwa zostanie podana.BŁĄD - Krótkie nazwy plików 8.3 mogą
/D
/S
uszkodzić opcje i Podobnie jak w przypadku wszystkich poleceń systemu Windows, FINDSTR będzie próbował dopasować zarówno długą nazwę, jak i krótką nazwę 8.3, podczas wyszukiwania plików do przeszukania. Załóżmy, że bieżący folder zawiera następujące niepuste pliki:
Następujące polecenie z powodzeniem znajdzie wszystkie 3 pliki:
b.txt2
pasuje, ponieważ odpowiada odpowiednia krótka nazwaB9F64~1.TXT
. Jest to zgodne z zachowaniem wszystkich innych poleceń systemu Windows.Ale błąd w opcjach
/D
i/S
powoduje, że następujące polecenia znajdują się tylkob1.txt
Błąd uniemożliwia
b.txt2
odnalezienie, a także wszystkich nazw plików posortowanych pob.txt2
tym samym katalogu.a.txt
Znaleziono dodatkowe pliki, które sortują się wcześniej . Dodatkowe pliki, które sortują później, na przykładd.txt
, są pomijane po uruchomieniu błędu.Każdy przeszukiwany katalog jest traktowany niezależnie. Na przykład
/S
opcja z powodzeniem rozpocznie wyszukiwanie w folderze podrzędnym po nieudanym znalezieniu plików w elemencie nadrzędnym, ale gdy błąd spowoduje pominięcie krótkiej nazwy pliku w elemencie podrzędnym, wówczas wszystkie kolejne pliki w tym folderze podrzędnym również zostaną pominięte .Polecenia działają bezbłędnie, jeśli te same nazwy plików są tworzone na komputerze z wyłączonym generowaniem nazw NTFS 8.3. Oczywiście
b.txt2
nie zostałby znaleziony, alec.txt
zostałby znaleziony poprawnie.Nie wszystkie krótkie nazwy powodują błąd. Wszystkie zaobserwowane przeze mnie przypadki błędnego zachowania dotyczą rozszerzenia dłuższego niż 3 znaki o krótkiej nazwie 8.3, która zaczyna się tak samo jak normalna nazwa, która nie wymaga nazwy 8.3.
Błąd został potwierdzony w systemach XP, Vista i Windows 7.
Znaków Niedrukowalny oraz
/P
opcja opcja powoduje FINDSTR pominąć dowolny plik, który zawiera jeden z następujących kodów bajtowych dziesiętnych: 0-7, 14-25, 27-31./P
Innymi słowy,
/P
opcja pomija tylko pliki zawierające niedrukowalne znaki kontrolne. Znaki kontrolne to kody mniejsze lub równe 31 (0x1F). FINDSTR traktuje następujące znaki kontrolne jako drukowalne:Wszystkie pozostałe znaki sterujące są traktowane jako niedrukowalne, których obecność powoduje, że
/P
opcja pomija plik.Dołączone dane wejściowe potokowe i przekierowane mogły zostać
<CR><LF>
dołączone.Jeśli dane wejściowe są przesyłane strumieniowo
<LF>
, a ostatni znak strumienia nie jest , funkcja FINDSTR automatycznie dołącza<CR><LF>
się do danych wejściowych. Zostało to potwierdzone w systemach XP, Vista i Windows 7. (Kiedyś myślałem, że potok Windows był odpowiedzialny za modyfikację danych wejściowych, ale od tego czasu odkryłem, że FINDSTR faktycznie dokonuje modyfikacji).To samo dotyczy przekierowanych danych wejściowych w systemie Vista. Jeśli ostatnim znakiem pliku używanego jako przekierowane dane wejściowe nie jest
<LF>
, wówczas FINDSTR automatycznie dołącza<CR><LF>
się do danych wejściowych. Jednak XP i Windows 7 nie zmieniają przekierowanych danych wejściowych.Findstr wisi na XP i Windows 7, jeśli przekierowany wejście nie kończy
<LF>
To jest paskudne „cecha” na XP i Windows 7. Jeśli ostatni znak pliku używany jako wejście przekierowanego nie kończy się
<LF>
, a następnie FINDSTR zawiśnie w nieskończoność po nim osiąga koniec przekierowanego pliku.Ostatni wiersz danych przesyłanych strumieniowo można zignorować, jeśli składa się z pojedynczego znaku.
Jeśli wejście jest przesyłane
<LF>
strumieniowo, a ostatni wiersz składa się z pojedynczego znaku, po którym nie następuje , funkcja FINDSTR całkowicie ignoruje ostatni wiersz.Przykład - Pierwsze polecenie z pojedynczym znakiem i bez niego
<LF>
nie pasuje, ale drugie polecenie z 2 znakami działa dobrze, podobnie jak trzecie polecenie, które ma jeden znak z zakończeniem nowej linii.Zgłoszony przez użytkownika DosTips Sponge Belly przy nowym błędzie findstr . Potwierdzono w XP, Windows 7 i Windows 8. Nie słyszałem jeszcze o Vistie. (Nie mam już Visty do przetestowania).
Składnia opcji
Opcje mogą być poprzedzone jednym z nich
/
lub-
Opcje mogą być łączone po jednym/
lub-
. Jednak połączona lista opcji może zawierać co najwyżej jedną opcję wieloznakową, taką jak WYŁ. Lub F :, a opcja wieloznakowa musi być ostatnią opcją na liście.Poniżej podano wszystkie równoważne sposoby wyrażenia wyrażenia regularnego bez rozróżniania wielkości liter dla dowolnego wiersza zawierającego zarówno „cześć”, jak i „do widzenia” w dowolnej kolejności
/i /r /c:"hello.*goodbye" /c:"goodbye.*hello"
-i -r -c:"hello.*goodbye" /c:"goodbye.*hello"
/irc:"hello.*goodbye" /c:"goodbye.*hello"
Limity długości ciągu wyszukiwania
W systemie Vista maksymalna dozwolona długość pojedynczego ciągu wyszukiwania wynosi 511 bajtów. Jeśli dowolny szukany ciąg przekracza 511, wynikiem jest
FINDSTR: Search string too long.
błąd z ERRORLEVEL 2.Podczas wyszukiwania wyrażeń regularnych maksymalna długość szukanego ciągu wynosi 254. Wyrażenie regularne o długości od 255 do 511 spowoduje
FINDSTR: Out of memory
błąd z ERRORLEVEL 2. Błąd wyrażenia regularnego> 511 spowodujeFINDSTR: Search string too long.
błąd.W systemie Windows XP długość ciągu wyszukiwania jest najwyraźniej krótsza. Błąd Findstr: „Ciąg wyszukiwania zbyt długi”: Jak wyodrębnić i dopasować podciąg w pętli „for”? Limit XP wynosi 127 bajtów dla wyszukiwania dosłownego i wyrażenia regularnego.
Limity długości linii
Pliki określone jako argument wiersza poleceń lub za pomocą opcji / F: FILE nie mają znanego limitu długości linii. Pomyślnie uruchomiono wyszukiwanie dla pliku 128 MB, który nie zawierał ani jednego <LF>.
Dane przesyłane potokowo i przekierowane dane wejściowe są ograniczone do 8191 bajtów na linię. Ten limit jest „funkcją” FINDSTR. Nie jest związany z potokami ani przekierowaniami. FINDSTR przy użyciu przekierowanego wejścia stdin lub potokowego nigdy nie będzie pasował do żadnej linii, która ma> 8k bajtów. Linie> = 8k generują komunikat o błędzie do stderr, ale ERRORLEVEL wciąż wynosi 0, jeśli szukany ciąg znajduje się w co najmniej jednym wierszu co najmniej jednego pliku.
Domyślny typ wyszukiwania:
/C:"string"
dosłowny vs. wyrażenie regularne - domyślnie jest to literał / L. Jawne połączenie opcji / L z / C: „string” z pewnością działa, ale jest redundantne."string argument"
- Wartość domyślna zależy od zawartości pierwszego szukanego ciągu. (Pamiętaj, że <spacja> jest używana do rozdzielenia ciągów wyszukiwania.) Jeśli pierwszy ciąg wyszukiwania jest prawidłowym wyrażeniem regularnym zawierającym co najmniej jeden nieoznakowany metaznak, wówczas wszystkie ciągi wyszukiwania są traktowane jako wyrażenia regularne. W przeciwnym razie wszystkie ciągi wyszukiwania są traktowane jak literały. Na przykład"51.4 200"
będą traktowane jako dwa wyrażenia regularne, ponieważ pierwszy ciąg zawiera kropkę bez znaku ucieczki, podczas gdy"200 51.4"
będzie traktowany jako dwa literały, ponieważ pierwszy ciąg nie zawiera żadnych metaznaków./G:file
- Wartość domyślna zależy od zawartości pierwszego niepustego wiersza w pliku. Jeśli pierwszy ciąg wyszukiwania jest prawidłowym wyrażeniem regularnym zawierającym co najmniej jeden nieoznakowany metaznak, wówczas wszystkie ciągi wyszukiwania są traktowane jako wyrażenia regularne. W przeciwnym razie wszystkie ciągi wyszukiwania są traktowane jak literały.Zalecenie - Zawsze używaj
/L
opcji dosłownie lub/R
opcji wyrażenia regularnego, gdy używasz"string argument"
lub/G:file
.BŁĄD - Podanie wielu dosłownych ciągów wyszukiwania może dać nierzetelne wyniki
Poniższy prosty przykład FINDSTR nie może znaleźć dopasowania, chociaż powinno.
Ten błąd został potwierdzony w systemach Windows Server 2003, Windows XP, Vista i Windows 7.
Na podstawie eksperymentów FINDSTR może się nie powieść, jeśli zostaną spełnione wszystkie następujące warunki:
/I
opcji)W każdej porażce, którą widziałem, zawsze zawodzi jeden z krótszych ciągów wyszukiwania.
Aby uzyskać więcej informacji, zobacz Dlaczego ten przykład FINDSTR z wieloma dosłownymi ciągami wyszukiwania nie znajduje dopasowania?
Cofanie
cudzysłowu i ukośnik odwrotny w / G: FILE dosłowne ciągi wyszukiwania Niezależne cytaty i odwrotne ukośniki w pliku dosłownego ciągu wyszukiwania określonego przez / G: plik nie muszą być poprzedzane, ale mogą być.
"
i\"
są równoważne.\
i\\
są równoważne.Jeśli celem jest znalezienie \\, to przynajmniej wiodący ukośnik odwrotny musi być poprzedzony znakiem ucieczki. Zarówno
\\\
i\\\\
praca.Jeśli intencją jest znalezienie \ ", to przynajmniej wiodący ukośnik odwrotny musi być poprzedzony. Oba
\\"
i\\\"
działają.Znak ucieczki cytatu i ukośnik odwrotny w ciągu / G: FILE ciągi wyszukiwania wyrażeń regularnych
Jest to jedyny przypadek, w którym sekwencje specjalne działają zgodnie z oczekiwaniami na podstawie dokumentacji. Cytat nie jest metaznakiem wyrażenia regularnego, więc nie trzeba go usuwać (ale może być). Ukośnik odwrotny jest metaznakiem wyrażenia regularnego, dlatego należy go usunąć.
Limity znaków dla parametrów wiersza poleceń - rozszerzona transformacja ASCII
Znak pusty (0x00) nie może pojawić się w żadnym ciągu w wierszu polecenia. W łańcuchu może pojawić się dowolny inny znak jednobajtowy (0x01 - 0xFF). Jednak FINDSTR konwertuje wiele rozszerzonych znaków ASCII, które znajdzie w parametrach wiersza poleceń, na inne znaki. Ma to duży wpływ na dwa sposoby:
1) Wiele rozszerzonych znaków ASCII nie będzie pasowało do siebie, jeśli zostanie użyty jako ciąg wyszukiwania w wierszu poleceń. To ograniczenie jest takie samo dla wyszukiwań literałowych i wyrażeń regularnych. Jeśli szukany ciąg musi zawierać rozszerzony ASCII,
/G:FILE
należy zamiast tego użyć opcji2) FINDSTR może nie znaleźć pliku, jeśli nazwa zawiera rozszerzone znaki ASCII, a nazwa pliku jest podana w wierszu poleceń. Jeśli plik do przeszukania zawiera rozszerzone ASCII w nazwie,
/F:FILE
należy zamiast tego użyć opcjiOto pełna lista rozszerzonych przekształceń znaków ASCII, które FINDSTR wykonuje na ciągach wiersza poleceń. Każdy znak jest reprezentowany jako dziesiętna wartość bajtu. Pierwszy kod reprezentuje znak podany w wierszu poleceń, a drugi kod reprezentuje znak, w który został przekształcony. Uwaga - ta lista została skompilowana na maszynie w USA. Nie wiem, jaki wpływ mogą mieć inne języki na tę listę.
Każdy znak> 0 niewymieniony na powyższej liście jest traktowany jak sam, w tym
<CR>
i <LF>
. Najprostszym sposobem na dołączenie nieparzystych znaków, takich jak<CR>
i,<LF>
jest umieszczenie ich w zmiennej środowiskowej i użycie opóźnionego rozwijania w argumencie wiersza poleceń.Limity znaków dla ciągów znalezionych w plikach określonych przez opcje / G: FILE i / F: FILE
W pliku może pojawić się znak nul (0x00), ale działa on jak terminator ciągów C. Wszelkie znaki po znaku nul są traktowane jako inny ciąg znaków, jakby znajdowały się w innym wierszu.
<CR>
I<LF>
znaki są traktowane jako terminatory linii, które kończą ciąg, a nie uwzględnionych w ciąg.Wszystkie pozostałe znaki jednobajtowe są doskonale zawarte w ciągu.
Wyszukiwanie plików Unicode
FINDSTR nie może poprawnie przeszukać większości Unicode (UTF-16, UTF-16LE, UTF-16BE, UTF-32), ponieważ nie może wyszukiwać nul bajtów, a Unicode zwykle zawiera wiele nul bajtów.
Jednak polecenie TYPE konwertuje UTF-16LE z BOM na zestaw znaków jednobajtowych, więc takie polecenie jak poniższe będzie działać z UTF-16LE z BOM.
Pamiętaj, że punkty kodu Unicode, które nie są obsługiwane przez twoją aktywną stronę kodową, zostaną przekonwertowane na
?
znaki.Możliwe jest wyszukiwanie UTF-8, o ile szukany ciąg zawiera tylko ASCII. Jednak dane wyjściowe konsoli wielobajtowych znaków UTF-8 nie będą prawidłowe. Ale jeśli przekierujesz dane wyjściowe do pliku, wynik zostanie poprawnie zakodowany UTF-8. Zauważ, że jeśli plik UTF-8 zawiera BOM, wówczas BOM będzie uważany za część pierwszego wiersza, co może uniemożliwić wyszukiwanie pasujące do początku wiersza.
Możliwe jest wyszukiwanie wielobajtowych znaków UTF-8, jeśli umieścisz szukany ciąg w pliku wyszukiwania zakodowanym w UTF-8 (bez BOM) i użyjesz opcji / G.
Koniec linii
FINDSTR przerywa linie natychmiast po każdym <LF>. Obecność lub brak <CR> nie ma wpływu na przerwy w linii.
Wyszukiwanie według podziałów linii
Zgodnie z oczekiwaniami,
.
metaznak wyrażenia regularnego nie będzie pasował do <CR> lub <LF>. Możliwe jest jednak przeszukiwanie podziału wiersza za pomocą ciągu wyszukiwania wiersza polecenia. Zarówno znaki <CR>, jak i <LF> muszą być wyraźnie dopasowane. W przypadku znalezienia dopasowania wieloliniowego drukowana jest tylko pierwsza linia dopasowania. FINDSTR następnie podwaja się do drugiej linii w źródle i rozpoczyna wyszukiwanie od nowa - coś w rodzaju funkcji „patrz przed siebie”.Załóżmy, że TEXT.TXT ma te treści (może być w stylu Unix lub Windows)
Potem ten skrypt
daje te wyniki
Przeszukiwanie podziałów wierszy za pomocą opcji / G: FILE jest niedokładne, ponieważ jedynym sposobem dopasowania <CR> lub <LF> jest wyrażenie wyrażenia zakresu klasy wyrażenia regularnego, które umieszcza znaki EOL.
[<TAB>-<0x0B>]
pasuje do <LF>, ale pasuje również do <TAB> i <0x0B>[<0x0C>-!]
pasuje do <CR>, ale pasuje również do <0x0C> i!Uwaga - powyższe są symbolicznymi reprezentacjami strumienia bajtów wyrażeń regularnych, ponieważ nie mogę graficznie przedstawić znaków.
Odpowiedź kontynuowana w części 2 poniżej ...
źródło
addpath.bat
z Q141344 i findstr, które mogą być związane z problemem zawieszania Win7 wymienionych powyżej. Stworzyłem pokój czatu, aby spróbować to wyśledzić, dla każdego, kto jest zainteresowany: chat.stackoverflow.com/rooms/13177/.../S
i/D
opcje wynikające z krótkich nazw plików 8.3.<LF>
Odpowiedź ciąg dalszy od części 1 powyżej - napotkałem limit odpowiedzi 30 000 znaków :-(
Ograniczona obsługa wyrażeń regularnych (regex) Obsługa
wyrażeń regularnych przez FINDSTR jest bardzo ograniczona. Jeśli nie ma go w dokumentacji POMOCY, nie jest obsługiwany.
Poza tym obsługiwane wyrażenia regularne są implementowane w całkowicie niestandardowy sposób, tak że wyniki mogą być inne niż można oczekiwać od grep lub perl.
Zakotwiczenia pozycji linii regex ^ i $
^
dopasowują początek strumienia wejściowego, a także dowolną pozycję bezpośrednio po <LF>. Ponieważ FINDSTR również łamie linie po <LF>, proste wyrażenie regularne „^” zawsze dopasuje wszystkie linie w pliku, nawet plik binarny.$
dopasowuje dowolną pozycję bezpośrednio poprzedzającą <CR>. Oznacza to, że ciąg wyrażenia regularnego zawierający$
nigdy nie będzie pasował do żadnych wierszy w pliku tekstowym w stylu uniksowym, ani nie będzie pasował do ostatniego wiersza pliku tekstowego Windows, jeśli brakuje znacznika EOL <CR> <LF>.Uwaga - Jak już wcześniej wspomniano, przesyłanie potokowe i przekierowane do FINDSTR mogło zostać
<CR><LF>
dołączone, ale nie w źródle. Oczywiście może to mieć wpływ na wyszukiwanie wyrażeń regularnych$
.Każdy ciąg znaków ze znakami przed
^
lub po$
zawsze nie znajdzie dopasowania.Opcje pozycyjne / B / E / X
Opcje pozycyjne działają tak samo jak
^
i$
, z tym wyjątkiem, że działają także w przypadku literalnych ciągów wyszukiwania./ B działa tak samo jak
^
na początku szukanego wyrażenia regularnego./ E działa tak samo jak
$
na końcu szukanego wyrażenia regularnego./ X działa tak samo, jak posiadanie zarówno
^
na początku, jak i$
na końcu szukanego wyrażenia regularnego.Granica słowa
\<
regex musi być pierwszym terminem w wyrażeniu regularnym. Wyrażenie regularne nie pasuje do niczego, jeśli poprzedzają go inne znaki.\<
odpowiada początkowi wejścia, początkowi wiersza (pozycja bezpośrednio po <LF>) lub pozycji bezpośrednio po dowolnym znaku „niebędącym słowem”. Następny znak nie musi być „słowem”.\>
musi być ostatnim terminem wyrażenia regularnego. Wyrażenie regularne nie pasuje do niczego, jeśli podążają za nim inne znaki.\>
odpowiada końcowi wprowadzania, pozycji bezpośrednio przed <CR> lub pozycji bezpośrednio poprzedzającej dowolny znak „niebędący słowem”. Poprzedni znak nie musi być „słowem”.Oto pełna lista znaków „niebędących słowami”, reprezentowanych jako dziesiętny kod bajtu. Uwaga - ta lista została skompilowana na maszynie w USA. Nie wiem, jaki wpływ mogą mieć inne języki na tę listę.
Zakresy klas znaków Regex [xy]
Zakresy klas znaków nie działają zgodnie z oczekiwaniami. Zobacz to pytanie: Dlaczego findstr nie obsługuje poprawnie sprawy (w niektórych okolicznościach)? , wraz z tą odpowiedzią: https://stackoverflow.com/a/8767815/1012053 .
Problem polega na tym, że FINDSTR nie zestawia znaków według ich bajtowej wartości kodu (powszechnie uważanej za kod ASCII, ale ASCII jest definiowany tylko od 0x00 - 0x7F). Większość implementacji wyrażeń regularnych traktowałoby [AZ] jak wielkie angielskie litery. Jednak FINDSTR używa sekwencji zestawiania, która z grubsza odpowiada działaniu SORT. Tak więc [AZ] zawiera pełny alfabet angielski, zarówno wielkie jak i małe litery (oprócz „a”), a także nieangielskie znaki alfabetu z znakami diakrytycznymi.
Poniżej znajduje się pełna lista wszystkich znaków obsługiwanych przez FINDSTR, posortowana w kolejności sortowania używanej przez FINDSTR do ustalenia zakresów klas wyrażeń regularnych. Znaki są reprezentowane jako ich dziesiętna wartość bajtu. Uważam, że sekwencja zestawiania jest najbardziej sensowna, jeśli znaki są wyświetlane przy użyciu strony kodowej 437. Uwaga - ta lista została skompilowana na maszynie w USA. Nie wiem, jaki wpływ mogą mieć inne języki na tę listę.
Limit terminu dla klasy znaków Regex i
BŁĄD FINDSTR nie tylko jest ograniczony do maksymalnie 15 terminów klasy znaków w wyrażeniu regularnym, ale nie obsługuje poprawnie próby przekroczenia limitu. Użycie 16 lub więcej terminów klas znaków powoduje interaktywne wyskakujące okienko Windows z informacją, że „Narzędzie Find String (QGREP) napotkało problem i musi zostać zamknięte. Przepraszamy za niedogodności”. Tekst wiadomości różni się nieznacznie w zależności od wersji systemu Windows. Oto jeden przykład FINDSTR, który zawiedzie:
Ten błąd został zgłoszony przez użytkownika DagoTips Judago tutaj . Zostało to potwierdzone w systemach XP, Vista i Windows 7.
Wyszukiwanie wyrażeń
regularnych kończy się niepowodzeniem (i może się zawiesić na czas nieokreślony), jeśli zawierają kod bajtowy 0xFF (dziesiętnie 255) Każde wyszukiwanie wyrażenia regularnego zawierające kod bajtowy 0xFF (dziesiętnie 255) zakończy się niepowodzeniem. Nie powiedzie się, jeśli kod bajtu 0xFF jest zawarty bezpośrednio lub jeśli jest domyślnie zawarty w zakresie klasy znaków. Pamiętaj, że zakresy klas znaków FINDSTR nie zestawiają znaków na podstawie wartości kodu bajtu. Postać
<0xFF>
pojawia się stosunkowo wcześnie w sekwencji zestawiania między<space>
i<tab>
. Tak więc dowolny zakres klas postaci, który obejmuje oba<space>
i<tab>
nie powiedzie się.Dokładne zachowanie zmienia się nieznacznie w zależności od wersji systemu Windows. Windows 7 zawiesza się bez końca, jeśli uwzględniono 0xFF. XP nie zawiesza się, ale zawsze nie może znaleźć dopasowania i od czasu do czasu drukuje następujący komunikat o błędzie - „Proces próbował zapisać do nieistniejącego potoku”.
Nie mam już dostępu do komputera z systemem Vista, więc nie mogłem testować w systemie Vista.
Błąd Regex:
.
i[^anySet]
może pasować do końca pliku Metaznakwyrażenia regularnego
.
powinien pasować tylko do dowolnego znaku innego niż<CR>
lub<LF>
. Istnieje błąd, który pozwala dopasować koniec pliku, jeśli ostatni wiersz w pliku nie jest zakończony przez<CR>
lub<LF>
. Jednak.
nie będzie pasować do pustego pliku.Na przykład plik o nazwie „test.txt” zawierający pojedynczą linię
x
, bez kończenia<CR>
lub<LF>
, będzie pasował do następującego:Ten błąd został potwierdzony na XP i Win7.
To samo wydaje się dotyczyć negatywnych zestawów znaków. Coś takiego
[^abc]
będzie pasować do końca pliku.[abc]
Wydaje się, że pozytywne zestawy znaków działają dobrze. Testowałem to tylko na Win7.źródło
type
dofindstr
.findstr
obsługuje wiele/c:
ciągów wyszukiwania. Wiem, że twoje odpowiedzi to pokazują. Ale jest to coś, co nie zostało udokumentowane; i byłem bardzo zaskoczony, gdy dowiedziałem się o tej funkcji pofindstr
kilku latach jej używania .LF
udokumentowanego problemu. Zdałem sobie sprawę, że mój plik testowy się nie skończył,LF
ponieważ użyłem gocopy
w trybie dołączania do jego utworzenia. Umieściłem sesję wiersza poleceń, aby zademonstrować problem w odpowiedzi ( stackoverflow.com/a/22943056/224704 ). Zauważ, że dane wejściowe nie są przekierowywane, a mimo to wyszukiwanie zawiesza się. Dokładnie to samo polecenie wyszukiwania nie zawiesza się z mniejszymi plikami, które podobnie się nie kończąLF
.findstr /R /C:"^[0-9][0-9]* [0-3][0-9][0-9]-[0-9][0-9]:[0-5][0-9]:[0-5][0-9]\.[0-9][0-9]* [0-9]*\.[0-9]*"
(15 klas postaci) -ErrorLevel = -1073740791 (0xC0000409)
, okno dialogowe błędu :Find String (QGREP) Utility has stopped working
; po usunięciu jednej klasy lub dwóch znaków meta (*\.
) działa ...findstr
czasami zawiesza się nieoczekiwanie podczas wyszukiwania dużych plików.Nie potwierdziłem dokładnych warunków ani rozmiarów granic. Podejrzewam, że każdy plik większy niż 2 GB może być zagrożony.
Miałem z tym mieszane doświadczenia, więc jest to coś więcej niż tylko rozmiar pliku. Wygląda na to, że może być odmianą FINDSTR zawiesza się na XP i Windows 7, jeśli przekierowane dane wejściowe nie kończą się na LF , ale jak pokazano, ten szczególny problem objawia się, gdy dane wejściowe nie są przekierowywane.
Poniższa sesja wiersza poleceń (Windows 7) pokazuje, jak
findstr
można zawiesić się podczas wyszukiwania pliku 3 GB.Uwaga: zweryfikowałem w edytorze szesnastkowym, że wszystkie linie są zakończone
CRLF
. Jedyną anomalią jest to, że plik jest kończony ze0x1A
względu na sposóbcopy
działania . Należy jednak pamiętać, że ta anomalia nie powoduje problemów w przypadku „małych” plików .Dzięki dodatkowym testom potwierdziłem, co następuje:
copy
z/b
opcją plików binarnych zapobiega dodawaniu0x1A
znaku ifindstr
nie zawiesza się na pliku 3 GB.findstr
zawieszenie się.0x1A
Postać nie powoduje żadnych problemów w „małej” pliku. (Podobnie w przypadku innych znaków kończących.)CRLF
po0x1A
rozwiązuje problem. (LF
samo w sobie prawdopodobnie by wystarczyło).type
do potokowania pliku dofindstr
prac bez zawieszenia. (Może to być spowodowane efektem ubocznym albotype
czy|
tego wstawia dodatkowy końca linii).<
również powodujefindstr
zawieszenie się. Ale tego się oczekuje; jak wyjaśniono w poście dbenham : „przekierowane dane wejściowe muszą kończyć się naLF
” .źródło
<LF>
. Plik o dwa bajty mniejszy nie zawiesił się. Bardzo paskudny!Gdy kilka poleceń jest zawartych w nawiasach, a pliki są przekierowywane do całego bloku:
... wtedy pliki pozostają otwarte, dopóki polecenia w bloku są aktywne, więc polecenia mogą przesunąć wskaźnik pliku przekierowanych plików. Zarówno polecenia WIĘCEJ, jak i ZNAJDŹ przesuwają wskaźnik pliku Stdin na początek pliku przed jego przetworzeniem, więc ten sam plik może być przetwarzany kilka razy w bloku. Na przykład ten kod:
... dają taki sam wynik jak ten:
Ten kod:
... dają taki sam wynik jak ten:
FINDSTR jest inny; to jednak nie przesunąć wskaźnik pliku stdin od aktualnej pozycji. Na przykład ten kod wstawia nowy wiersz po wierszu wyszukiwania:
Możemy dobrze wykorzystać tę funkcję za pomocą programu pomocniczego, który pozwala nam przenieść wskaźnik pliku przekierowanego pliku, jak pokazano w tym przykładzie .
To zachowanie zostało po raz pierwszy zgłoszone przez jeb w tym poście .
EDYCJA 2018-08-18 : Zgłoszono nowy błąd FINDSTR
Polecenie FINDSTR ma dziwny błąd, który występuje, gdy to polecenie służy do wyświetlania znaków w kolorze ORAZ wynik takiego polecenia jest przekierowywany do urządzenia CON. Szczegółowe informacje na temat używania polecenia FINDSTR do wyświetlania tekstu w kolorze można znaleźć w tym temacie .
Gdy dane wyjściowe tej formy polecenia FINDSTR są przekierowywane do CON, po wyjściu tekstu w pożądanym kolorze dzieje się coś dziwnego: cały tekst po tym, jak jest wyświetlany jako „niewidoczny” znak, chociaż dokładniejszy opis jest taki, że tekst jest wyjście w postaci czarnego tekstu na czarnym tle. Oryginalny tekst pojawi się, jeśli użyjesz polecenia KOLOR, aby zresetować kolory pierwszego planu i tła na całym ekranie. Jednak gdy tekst jest „niewidoczny”, możemy wykonać polecenie SET / P, więc wszystkie wprowadzone znaki nie pojawią się na ekranie. Tego zachowania można użyć do wprowadzenia haseł.
źródło
Chciałbym zgłosić błąd dotyczący sekcji Źródło danych do przeszukania w pierwszej odpowiedzi przy użyciu en dash (-) lub em dash (-) w nazwie pliku.
Mówiąc dokładniej, jeśli zamierzasz użyć pierwszej opcji - nazw plików określonych jako argumenty , plik nie zostanie znaleziony. Gdy tylko użyjesz opcji 2 - stdin poprzez przekierowanie lub 3 - strumień danych z potoku , findstr znajdzie plik.
Na przykład ten prosty skrypt wsadowy:
wydrukuje:
Nazwa pliku z en dash:
Jako argument
FINDSTR: Nie można otworzyć nazwy pliku za pomocą - dash.txt
Jako stdin poprzez przekierowanie
jestem plikiem z myślnikiem.
Jako strumień danych z potoku
jestem plikiem z myślnikiem.
Nazwa pliku z em myślnikiem:
Jako argument
FINDSTR: Nie można otworzyć nazwy pliku za pomocą - dash.txt
Jako stdin poprzez przekierowanie
jestem plikiem z myślnikiem.
Jako strumień danych z potoku
jestem plikiem z myślnikiem.
Mam nadzieję, że to pomoże.
M.
źródło
findstr
Polecenie ustawiaErrorLevel
(lub wyjście) kodu do jednego z następujących wartości, jako że nie ma żadnych nieprawidłowych lub niezgodne przełączniki i ma ciąg wyszukiwania przekracza odpowiadającej maksymalnej długości:0
gdy w jednym wierszu napotkane zostanie co najmniej jedno dopasowanie we wszystkich określonych plikach;1
Inaczej;Uważa się, że wiersz zawiera dopasowanie, gdy:
/V
podano żadnej opcji i wyrażenie wyszukiwania występuje co najmniej raz;/V
opcja jest podana i wyrażenie wyszukiwania nie występują;Oznacza to, że
/V
opcja zmienia również zwracanyErrorLevel
, ale nie tylko go przywraca!Na przykład, jeśli masz plik
test.txt
z dwoma wierszami, z których jeden zawiera ciąg,text
a drugi nie, obafindstr "text" "test.txt"
ifindstr /V "text" "test.txt"
zwracają jedenErrorLevel
z nich0
.Zasadniczo możesz powiedzieć: jeśli
findstr
zwraca przynajmniej linię,ErrorLevel
jest ustawiona na0
, w przeciwnym razie1
.Zauważ, że
/M
opcja nie wpływa naErrorLevel
wartość, tylko zmienia wynik.(Ze względu na kompletność:
find
polecenie zachowuje się dokładnie tak samo w odniesieniu do/V
opcji iErrorLevel
;/C
opcja nie ma wpływuErrorLevel
).źródło
FINDSTR ma błąd koloru, który opisałem i rozwiązałem na /superuser/1535810/is-there-a-better-way-to-mitigate-this-obscure-color-bug-when-piping-to -findstr / 1538802? noredirect = 1 # comment2339443_1538802
Podsumowując ten wątek, błąd polega na tym, że jeśli dane wejściowe są przesyłane do FINDSTR w nawiasowym bloku kodu, wbudowane kody ucieczki ANSI przestają działać w poleceniach wykonanych później. Przykładem wbudowanych kodów kolorów jest:
echo %magenta%Alert: Something bad happened%yellow%
(gdzie magenta i żółty to zmienne zdefiniowane wcześniej w pliku .bat jako odpowiadające im kody ucieczki ANSI).Moim początkowym rozwiązaniem było wywołanie podprogramu „nic nie rób” po FINDSTR. W jakiś sposób połączenie lub powrót „resetuje” wszystko, co wymaga zresetowania.
Później odkryłem inne rozwiązanie, które prawdopodobnie jest bardziej wydajne: umieść frazę FINDSTR w nawiasach, jak w poniższym przykładzie:
echo success | ( FINDSTR /R success )
Umieszczenie frazy FINDSTR w zagnieżdżonym bloku kodu wydaje się izolować błąd kodu koloru FINDSTR, aby nie wpływał na to, co znajduje się poza zagnieżdżonym blok. Być może ta technika rozwiąże również inne niepożądane skutki uboczne FINDSTR .źródło
/ D wskazówka dla wielu katalogów: umieść listę katalogów przed wyszukiwanym ciągiem. Wszystkie działają:
Zgodnie z oczekiwaniami ścieżka jest względna do lokalizacji, jeśli nie uruchamiasz katalogów
\
. Otaczanie ścieżki"
jest opcjonalne, jeśli w nazwach katalogów nie ma spacji. Zakończenie\
jest opcjonalne. Dane wyjściowe lokalizacji będą zawierać podaną przez ciebie ścieżkę. Będzie działać z otoczeniem listy katalogów lub bez niej"
.źródło
/D:dirlist Search a semicolon-delimited list of directories
i jest umieszczony przed ciągiem wyszukiwania, więc nie rozumiem, co dokładnie jest „znalezione” w przełączniku / D (i jakie są polecenia, które NIE działają ") ...findstr
Najpierw rozumiem dokumentację dla list / D. Tak, nie mam żadnych argumentów w związku z dokumentowaniem funkcji, po prostu nie udokumentowano gotcha, że kolejność atrybutów ma znaczenie. Wykonuję bardzo mało pracy z wierszem poleceń, więc kiedy brukowałem polecenie, nie wiedząc, że kolejność robi różnicę, po prostu dodawałem atrybuty, kiedy do nich dotarłem (i alfabetycznie C poprzedza D). Byłem naprawdę sfrustrowany i podzieliłem się swoim doświadczeniem dla każdego, kto nie pracuje zbyt wiele z wierszem poleceń.findstr
Dokumentacja określić, żestrings
jest to NIE opcjonalne i że należy go umieścić po opcjonalnych atrybutów i przed opcjonalnym listy nazw. Jeśli „znalezione” to to, że użycie polecenia bez przestrzegania formatu użycia powoduje błąd, to taki punkt jest dobrze udokumentowany. Zobacz Składnia polecenia : „Składnia pojawia się w kolejności, w której należy wpisać polecenie i wszelkie parametry, które po nim następują”