La commande Windows FINDSTR est documentée de manière horrible. Une aide en ligne de commande très simple est disponible via FINDSTR /?
, ou HELP FINDSTR
, mais il est malheureusement insuffisant. Il existe un peu plus de documentation en ligne à l’ adresse http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/findstr.mspx?mfr=true .
De nombreuses fonctionnalités et limitations de FINDSTR ne sont même pas mentionnées dans la documentation. Ils ne pouvaient pas non plus être anticipés sans connaissance préalable et / ou expérimentation minutieuse.
Donc, la question est – Quelles sont les fonctionnalités et les limitations non documentées de FINDSTR?
Le but de cette question est de fournir un référentiel unique des nombreuses fonctionnalités non documentées afin que:
A) Les développeurs peuvent tirer pleinement parti des fonctionnalités disponibles.
B) Les développeurs ne perdent pas leur temps à se demander pourquoi quelque chose ne fonctionne pas quand cela semble nécessaire.
Assurez-vous de connaître la documentation existante avant de répondre. Si l’information est couverte par HELP, elle n’appartient pas ici.
Ce n’est pas non plus un endroit pour montrer des utilisations intéressantes de FINDSTR. Si une personne logique pouvait anticiper le comportement d’une utilisation particulière de FINDSTR en fonction de la documentation, elle n’appartient pas ici.
Dans le même ordre d’idées, si une personne logique pouvait anticiper le comportement d’un usage particulier sur la base des informations contenues dans les réponses existantes, elle n’appartient pas à nouveau ici.
Préface
La plupart des informations contenues dans cette réponse ont été rassemblées à partir d’expériences réalisées sur une machine Vista. Sauf mention contraire explicite, je n’ai pas confirmé si les informations s’appliquent à d’autres versions de Windows.
Sortie FINDSTR
La documentation ne dérange jamais pour expliquer la sortie de FINDSTR. Cela fait allusion au fait que les lignes correspondantes sont imprimées, mais rien de plus.
Le format de sortie de ligne correspondant est le suivant:
filename: lineNumber: lineOffset: texte
où
fileName: = Nom du fichier contenant la ligne correspondante. Le nom du fichier n’est pas imprimé si la demande était explicitement pour un fichier unique ou si vous recherchez une entrée redissortingbuée ou une entrée redirigée. Une fois imprimé, le nom de fichier inclura toujours toute information de chemin fournie. Des informations de chemin supplémentaires seront ajoutées si l’option /S
est utilisée. Le chemin imprimé est toujours relatif au chemin fourni ou relatif au répertoire actuel si aucun n’est fourni.
Remarque – Le préfixe de nom de fichier peut être évité lors de la recherche de plusieurs fichiers en utilisant les caractères génériques non standard (et peu documentés) <
et >
. Les règles exactes sur le fonctionnement de ces caractères génériques peuvent être trouvées ici . Enfin, vous pouvez regarder cet exemple de fonctionnement des caractères génériques non standard avec FINDSTR .
lineNumber: = Le numéro de la ligne correspondante représentée par une valeur décimale avec 1 représentant la 1ère ligne de l'entrée. Seule l’impression si /N
option est spécifiée.
lineOffset: = Le décalage en octets décimal du début de la ligne correspondante, avec 0 représentant le 1er caractère de la 1ère ligne. Seule l'option if /O
imprimée est spécifiée. Ce n'est pas le décalage de la correspondance dans la ligne. C'est le nombre d'octets du début du fichier au début de la ligne.
text = Représentation binary de la ligne correspondante, y compris les
FINDSTR "^" FILE >FILE_COPY
La plupart des caractères de contrôle et de nombreux caractères ASCII étendus s'affichent sous forme de points sur XP
FINDSTR sur XP affiche la plupart des caractères de contrôle non imprimables des lignes correspondantes sous forme de points (points) à l'écran. Les caractères de contrôle suivants sont des exceptions. ils s'affichent eux-mêmes: onglet 0x09, saut de ligne 0x0A, onglet vertical 0x0B, stream de formulaire 0x0C, retour de chariot 0x0D.
XP FINDSTR convertit également un certain nombre de caractères ASCII étendus en points. Les caractères ASCII étendus qui s'affichent sous forme de points sur XP sont les mêmes que ceux transformés lorsqu'ils sont fournis sur la ligne de commande. Voir la section "Limites de caractères pour les parameters de ligne de commande - Transformation ASCII étendue" , plus loin dans cet article.
Les caractères de contrôle et les caractères ASCII étendus ne sont pas convertis en points sur XP si la sortie est redirigée vers un fichier ou dans une clause FOR IN ().
Vista et Windows 7 affichent toujours tous les caractères eux-mêmes, jamais comme des points.
Codes de retour (ERRORLEVEL)
/A:xx
/L
et /R
spécifiées /A:
/F:
/C:
/D:
ou /G:
/F:file
ou /G:file
introuvable Source de données à rechercher (mise à jour basée sur des tests sous Windows 7)
Findstr peut rechercher des données à partir d'une seule des sources suivantes:
noms de fichiers spécifiés comme arguments et / ou en utilisant l’option /F:file
.
stdin via redirection findstr "searchSsortingng"
stream de données d'un type file | findstr "searchSsortingng"
conduite type file | findstr "searchSsortingng"
type file | findstr "searchSsortingng"
Les arguments / options ont priorité sur la redirection, qui a priorité sur les données diffusées.
Les arguments de nom de fichier et /F:file
peuvent être combinés. Plusieurs arguments de nom de fichier peuvent être utilisés. Si plusieurs options de /F:file
sont spécifiées, seul le dernier est utilisé. Les caractères génériques sont autorisés dans les arguments de nom de fichier, mais pas dans le fichier désigné par /F:file
.
Source des chaînes de recherche (mise à jour basée sur des tests sous Windows 7)
Les options /G:file
et /C:ssortingng
peuvent être combinées. Multiple /C:ssortingng
options de /C:ssortingng
peuvent être spécifiées. Si plusieurs options de /G:file
sont spécifiées, seul le dernier est utilisé. Si l'un des /G:file
ou /C:ssortingng
est utilisé, tous les arguments autres que les options sont supposés être des fichiers à rechercher. Si ni /G:file
ni /C:ssortingng
n'est utilisé, le premier argument non-option est traité comme une liste de termes de recherche délimitée par des espaces.
Les noms de fichiers ne doivent pas être cités dans le fichier lorsque vous utilisez l'option /F:FILE
.
Les noms de fichiers peuvent contenir des espaces et d'autres caractères spéciaux. La plupart des commandes exigent que ces noms de fichiers soient cités. Mais l'option FINDSTR /F:files.txt
requirejs que les noms de fichiers dans files.txt ne doivent PAS être cités. Le fichier ne sera pas trouvé si le nom est cité.
BOGUE - Les noms de fichiers courts 8.3 peuvent casser les options /D
et /S
Comme avec toutes les commandes Windows, FINDSTR essaiera de faire correspondre le nom long et le nom abrégé 8.3 lors de la recherche de fichiers à rechercher. Supposons que le dossier actuel contient les fichiers non vides suivants:
b1.txt b.txt2 c.txt
La commande suivante trouvera tous les 3 fichiers avec succès:
findstr /m "^" *.txt
b.txt2
correspond car le nom court correspondant B9F64~1.TXT
correspond. Ceci est cohérent avec le comportement de toutes les autres commandes Windows.
Mais un bogue avec les options /D
et /S
entraîne les commandes suivantes uniquement pour trouver b1.txt
findstr /m /d:. "^" *.txt findstr /m /s "^" *.txt
Le bogue empêche la b.txt2
de b.txt2
, ainsi que tous les noms de fichiers qui sortingent après b.txt2
dans le même répertoire. Des fichiers supplémentaires qui sont a.txt
auparavant, comme a.txt
, sont trouvés. Les fichiers supplémentaires d.txt
plus tard, comme d.txt
, sont manqués une fois le bogue déclenché.
Chaque répertoire recherché est traité indépendamment. Par exemple, l’option /S
commencerait avec succès la recherche dans un dossier enfant après l’échec de la recherche des fichiers dans le parent, mais une fois que le bogue provoquera un manque de nom de fichier dans l’enfant, tous les fichiers ultérieurs de ce dossier manquer.
Les commandes fonctionnent sans bogue si les mêmes noms de fichiers sont créés sur une machine sur laquelle la génération de noms NTFS 8.3 est désactivée. Bien sûr, b.txt2
ne serait pas trouvé, mais c.txt
serait trouvé correctement.
Tous les noms courts ne déclenchent pas le bogue. Toutes les instances de comportement buggé que j'ai vues impliquent une extension de plus de 3 caractères avec un nom court 8.3 qui commence comme un nom normal qui ne nécessite pas de nom 8.3.
Le bogue a été confirmé sur XP, Vista et Windows 7.
Caractères non imprimables et option /P
L'option /P
oblige FINDSTR à ignorer tout fichier contenant l'un des codes d'octet décimal suivants:
0-7, 14-25, 27-31.
En d'autres termes, l'option /P
ignore uniquement les fichiers contenant des caractères de contrôle non imprimables. Les caractères de contrôle sont des codes inférieurs ou égaux à 31 (0x1F). FINDSTR traite les caractères de contrôle suivants comme imprimables:
8 0x08 backspace 9 0x09 horizontal tab 10 0x0A line feed 11 0x0B vertical tab 12 0x0C form feed 13 0x0D carriage return 26 0x1A substitute (end of text)
Tous les autres caractères de contrôle sont traités comme non imprimables, la présence de ceux-ci entraînant l’option /P
pour ignorer le fichier.
Les entrées canalisées et redirigées peuvent avoir
ajouté
Si l'entrée est redirigée et que le dernier caractère du stream n'est pas
, alors FINDSTR ajoute automatiquement
à l'entrée. Cela a été confirmé sur XP, Vista et Windows 7. (Je pensais que le tube Windows était responsable de la modification de l'entrée, mais j'ai depuis découvert que FINDSTR est en train de faire la modification.)
La même chose est vraie pour les entrées redirigées sur Vista. Si le dernier caractère d'un fichier utilisé comme entrée redirigée n'est pas
, alors FINDSTR ajoute automatiquement
à l'entrée. Cependant, XP et Windows 7 ne modifient pas les entrées redirigées.
FINDSTR se bloque sur XP et Windows 7 si l’entrée redirigée ne se termine pas par
C'est une "fonctionnalité" désagréable sur XP et Windows 7. Si le dernier caractère d'un fichier utilisé comme entrée redirigée ne se termine pas par
, alors FINDSTR se bloquera indéfiniment une fois qu'il atteindra la fin du fichier redirigé.
La dernière ligne de données canalisées peut être ignorée si elle consiste en un seul caractère
Si l'entrée est redirigée et que la dernière ligne est constituée d'un seul caractère qui n'est pas suivi par
, alors FINDSTR ignore complètement la dernière ligne.
Exemple - La première commande avec un seul caractère et sans
ne correspond pas, mais la deuxième commande avec 2 caractères fonctionne correctement, de même que la troisième commande comportant un caractère avec terminaison de ligne.
> set /p "=x" set /p "=xx" echo x| findstr "^" x
Signalé par l'utilisateur DosTips Sponge Belly au nouveau bug findstr . Confirmé sur XP, Windows 7 et Windows 8. Je n'ai pas encore entendu parler de Vista. (Je n'ai plus Vista à tester).
Syntaxe d'option
Les options peuvent être préfixées par /
ou -
options peuvent être concaténées après un seul /
ou -
. Cependant, la liste d'options concaténée peut contenir au plus une option multi-caractères telle que OFF ou F: et l'option multi-caractères doit être la dernière option de la liste.
Les méthodes suivantes permettent d'exprimer une recherche d'expression rationnelle insensible à la casse pour toute ligne contenant à la fois "salut" et "au revoir" dans n'importe quel ordre.
/i /r /c:"hello.*goodbye" /c:"goodbye.*hello"
-i -r -c:"hello.*goodbye" /c:"goodbye.*hello"
/irc:"hello.*goodbye" /c:"goodbye.*hello"
Limites de longueur de la chaîne de recherche
Sur Vista, la longueur maximale autorisée pour une seule chaîne de recherche est de 511 octets. Si une chaîne de recherche dépasse 511, le résultat est une FINDSTR: Search ssortingng too long.
erreur avec ERRORLEVEL 2.
Lorsque vous effectuez une recherche d'expression régulière, la longueur maximale de la chaîne de recherche est 254. Une expression régulière d'une longueur comprise entre 255 et 511 entraîne une FINDSTR: Out of memory
avec ERRORLEVEL 2. Une longueur d'expression régulière> 511 entraîne la recherche FINDSTR: Search ssortingng too long.
Erreur.
Sur Windows XP, la longueur de la chaîne de recherche est apparemment plus courte. Erreur Findstr: "Chaîne de recherche trop longue": Comment extraire et faire correspondre une sous-chaîne dans une boucle "for"? La limite de XP est de 127 octets pour les recherches littérales et rationnelles.
Limites de longueur de ligne
Les fichiers spécifiés en tant qu'argument de ligne de commande ou via l'option / F: FILE n'ont aucune limite de longueur de ligne connue. Les recherches ont été exécutées avec succès sur un fichier de 128 Mo qui ne contenait pas un seul
Les données canalisées et les entrées redirigées sont limitées à 8191 octets par ligne. Cette limite est une "fonctionnalité" de FINDSTR. Ce n'est pas inhérent aux tuyaux ou à la redirection. FINDSTR utilisant une entrée stdin redirigée ou une entrée redirigée ne correspondra à aucune ligne> = 8k octets. Les lignes> = 8k génèrent un message d'erreur à stderr, mais ERRORLEVEL est toujours à 0 si la chaîne de recherche est trouvée dans au moins une ligne d'au moins un fichier.
Type de recherche par défaut: expression littérale vs expression régulière
/C:"ssortingng"
- La valeur par défaut est / L literal. Combiner explicitement l'option / L avec / C: "ssortingng" fonctionne certes, mais est redondante.
"ssortingng argument"
- La valeur par défaut dépend du contenu de la toute première chaîne de recherche. (N'oubliez pas que "51.4 200"
sera traité comme deux expressions régulières car la première chaîne contient un point non échappé, tandis que "200 51.4"
sera traité comme deux littéraux car la première chaîne ne contient aucun méta-caractère.
/G:file
- La valeur par défaut dépend du contenu de la première ligne non vide du fichier. Si la première chaîne de recherche est une expression régulière valide contenant au moins un méta-caractère non échappé, toutes les chaînes de recherche sont traitées comme des expressions régulières. Sinon, toutes les chaînes de recherche sont traitées comme des littéraux.
Recommandation - Toujours spécifier explicitement l'option /L
option littérale ou l'option /R
expression régulière lors de l'utilisation de "ssortingng argument"
ou /G:file
.
BOGUE - Spécifier plusieurs chaînes de recherche littérale peut donner des résultats peu fiables
L'exemple FINDSTR simple suivant ne parvient pas à trouver une correspondance, même si elle le devrait.
echo ffffaaa|findstr /l "ffffaaa faffaffddd"
Ce bogue a été confirmé sur Windows Server 2003, Windows XP, Vista et Windows 7.
Sur la base d'expériences, FINDSTR peut échouer si toutes les conditions suivantes sont remplies:
/I
) À chaque échec que j'ai vu, c'est toujours l'une des chaînes de recherche les plus courtes qui échouent.
Pour plus d'informations, voir Pourquoi cet exemple FINDSTR avec plusieurs chaînes de recherche littérale ne trouve-t-il pas une correspondance?
Citations et slashs dans les arguments de la ligne de commande - Note:
Les informations contenues dans cette section en surbrillance ne sont pas exactes à 100%. Après avoir écrit cette section, l'utilisateur MC ND m'a indiqué une référence documentant comment la bibliothèque Microsoft C / C ++ parsing les parameters . C'est horriblement compliqué, mais il semble prédire avec précision les barres obliques inverses et les règles de cotation pour les arguments de la ligne de commande FINDSTR. Je vous recommande d'utiliser les informations surlignées ci-dessous comme guide, mais si vous souhaitez des informations plus précises, reportez-vous au lien.Citation échappée dans les chaînes de recherche de ligne de commande
Les guillemets dans les chaînes de recherche de ligne de commande doivent être précédés d'une barre oblique inversée telle que\"
. Cela est vrai pour les chaînes de recherche littérale et regex. Ces informations ont été confirmées sur XP, Vista et Windows 7.Remarque: Le devis peut également devoir être échappé pour l'parsingur CMD.EXE, mais cela n'a rien à voir avec FINDSTR. Par exemple, pour rechercher un seul devis, vous pouvez utiliser:
FINDSTR \^" file && echo found || echo not found
Échapper à la barre oblique inverse dans les chaînes de recherche littérale de ligne de commande
La barre oblique inverse dans une chaîne de recherche littérale peut normalement être représentée par\
ou par\\
. Ils sont généralement équivalents. (Il peut y avoir des cas inhabituels dans Vista où la barre oblique inverse doit toujours être échappée, mais je n'ai plus de machine Vista à tester) .Mais il y a des cas particuliers:
Lors de la recherche de barres obliques inverses consécutives, toutes les exceptions sauf la dernière doivent être évitées. Le dernier backslash peut éventuellement être échappé.
\\
peut être codé comme\\\
ou\\\\
\\\
peut être codé comme\\\\\\
ou\\\\\\
Rechercher une ou plusieurs barres obliques inverses avant qu'une citation ne soit bizarre. La logique suggérerait que la citation doit être échappée, et chacune des barres obliques inverses principales devrait être échappée, mais cela ne fonctionne pas! Au lieu de cela, chacune des barres obliques inverses doit être échappée deux fois et le devis est échappé normalement:
\"
doit être codé comme\\\\\"
\\"
doit être codé comme\\\\\\\\\"
Comme indiqué précédemment, un ou plusieurs guillemets évités peuvent également nécessiter une échappée avec
^
pour l'parsingur CMD.Les informations de cette section ont été confirmées sur XP et Windows 7.
Échapper à la barre oblique inverse dans les chaînes de recherche de regex en ligne de commande
Vista uniquement: la barre oblique inverse dans une regex doit être soit double échappée comme
\\\\
, soit simple échappée dans un jeu de classes de caractères comme[\\]
XP et Windows 7: la barre oblique inverse dans une expression régulière peut toujours être représentée par
[\\]
. Il peut normalement être représenté par\\
. Mais cela ne fonctionne jamais si la barre oblique inverse précède une citation échappée.Une ou plusieurs barres obliques inverses avant qu'un guillemet échappé doive soit être échappé double, soit être codé comme
[\\]
\"
peut être codé comme\\\\\"
ou[\\]\"
\\"
peut être codé comme\\\\\\\\\"
ou[\\][\\]\"
ou\\[\\]\"
Citation et barre oblique inversée dans / G: chaînes de recherche littérale FILE
Les guillemets et les barres obliques inverses dans un fichier de chaîne de recherche littéral spécifié par / G: file ne doivent pas être échappés, mais ils peuvent l'être.
"
et \"
sont équivalents.
\
et \\
sont équivalents.
Si l'intention est de trouver \\, alors au moins la barre oblique inverse doit être échappée. Les deux \\\
et \\\\
fonctionnent.
Si l'intention est de trouver \ ", alors au moins la barre oblique inversée doit être échappée. Les deux \\"
et \\\"
fonctionnent.
Échappement à la cotation et à la barre oblique inverse dans / G: chaînes de recherche de regex FILE
C'est le seul cas où les séquences d'échappement fonctionnent comme prévu en fonction de la documentation. Quote n'est pas un métacaractère de regex, il n'a donc pas besoin d'être échappé (mais peut l'être). La barre oblique inverse est un métacaractère de regex, il doit donc être échappé.
Limites de caractères pour les parameters de ligne de commande - Transformation ASCII étendue
Le caractère nul (0x00) ne peut apparaître dans aucune chaîne de la ligne de commande. Tout autre caractère simple octet peut apparaître dans la chaîne (0x01 - 0xFF). Toutefois, FINDSTR convertit de nombreux caractères ASCII étendus trouvés dans les parameters de ligne de commande en d'autres caractères. Cela a un impact majeur de deux manières:
1) De nombreux caractères ASCII étendus ne correspondront pas s'ils sont utilisés comme chaîne de recherche sur la ligne de commande. Cette limitation est la même pour les recherches littérales et rationnelles. Si une chaîne de recherche doit contenir un code ASCII étendu, l'option /G:FILE
doit être utilisée à la place.
2) FINDSTR peut ne pas trouver de fichier si le nom contient des caractères ASCII étendus et si le nom du fichier est spécifié sur la ligne de commande. Si un fichier à rechercher contient un nom ASCII étendu, l'option /F:FILE
doit être utilisée à la place.
Voici une liste complète des transformations de caractères ASCII étendues que FINDSTR exécute sur les chaînes de lignes de commande. Chaque caractère est représenté par la valeur du code octet décimal. Le premier code représente le caractère fourni sur la ligne de commande et le second code représente le caractère dans lequel il est transformé. Remarque - cette liste a été compilée sur une machine américaine. Je ne sais pas quel impact d'autres langues peuvent avoir sur cette liste.
158 treated as 080 199 treated as 221 226 treated as 071 169 treated as 170 200 treated as 043 227 treated as 112 176 treated as 221 201 treated as 043 228 treated as 083 177 treated as 221 202 treated as 045 229 treated as 115 178 treated as 221 203 treated as 045 231 treated as 116 179 treated as 221 204 treated as 221 232 treated as 070 180 treated as 221 205 treated as 045 233 treated as 084 181 treated as 221 206 treated as 043 234 treated as 079 182 treated as 221 207 treated as 045 235 treated as 100 183 treated as 043 208 treated as 045 236 treated as 056 184 treated as 043 209 treated as 045 237 treated as 102 185 treated as 221 210 treated as 045 238 treated as 101 186 treated as 221 211 treated as 043 239 treated as 110 187 treated as 043 212 treated as 043 240 treated as 061 188 treated as 043 213 treated as 043 242 treated as 061 189 treated as 043 214 treated as 043 243 treated as 061 190 treated as 043 215 treated as 043 244 treated as 040 191 treated as 043 216 treated as 043 245 treated as 041 192 treated as 043 217 treated as 043 247 treated as 126 193 treated as 045 218 treated as 043 249 treated as 250 194 treated as 045 219 treated as 221 251 treated as 118 195 treated as 043 220 treated as 095 252 treated as 110 196 treated as 045 222 treated as 221 254 treated as 221 197 treated as 043 223 treated as 095 198 treated as 221 224 treated as 097
Tout caractère> 0 ne figurant pas dans la liste ci-dessus est traité comme tel, y compris
et < LF>
. La méthode la plus simple pour inclure des caractères impairs comme
et
consiste à les placer dans une variable d’environnement et à utiliser l’expansion retardée dans l’argument de la ligne de commande.
Limites de caractères pour les chaînes trouvées dans les fichiers spécifiés par les options / G: FILE et / F: FILE
Le caractère nul (0x00) peut apparaître dans le fichier, mais il fonctionne comme le terminateur de chaîne C. Tous les caractères après un caractère nul sont traités comme une chaîne différente comme s'ils étaient sur une autre ligne.
Les caractères
et
sont traités comme des terminateurs de ligne qui terminent une chaîne et ne sont pas inclus dans la chaîne.
Tous les autres caractères à un octet sont parfaitement inclus dans une chaîne.
Recherche de fichiers Unicode
FINDSTR ne peut pas rechercher correctement la plupart des Unicode (UTF-16, UTF-16LE, UTF-16BE, UTF-32) car il ne peut rechercher aucun octet et Unicode contient généralement de nombreux octets nuls.
Cependant, la commande TYPE convertit UTF-16LE avec la nomenclature en un jeu de caractères à un seul octet. Par conséquent, une commande comme celle-ci fonctionnera avec UTF-16LE avec la nomenclature.
type unicode.txt|findstr "search"
Notez que les points de code Unicode qui ne sont pas pris en charge par votre page de code active seront convertis en ?
personnages.
Il est possible de rechercher UTF-8 tant que votre chaîne de recherche contient uniquement des caractères ASCII. Cependant, la sortie de la console de tous les caractères multi-octets UTF-8 ne sera pas correcte. Mais si vous redirigez la sortie vers un fichier, le résultat sera correctement encodé en UTF-8. Notez que si le fichier UTF-8 contient une nomenclature, la nomenclature sera considérée comme faisant partie de la première ligne, ce qui pourrait déclencher une recherche correspondant au début d'une ligne.
Il est possible de rechercher des caractères multi-octets UTF-8 si vous placez votre chaîne de recherche dans un fichier de recherche encodé en UTF-8 (sans nomenclature) et utilisez l'option / G.
Fin de ligne
FINDSTR rompt les lignes immédiatement après chaque
Recherche à travers des sauts de ligne
Comme prévu, le .
le métacaractère de regex ne correspondra pas à
Supposons que TEXT.TXT a ce contenu (peut être un style Unix ou Windows)
A A A B A A
Alors ce script
@echo off setlocal ::Define LF variable containing a linefeed (0x0A) set LF=^ ::Above 2 blank lines are critical - do not remove ::Define CR variable containing a carriage return (0x0D) for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a" setlocal enableDelayedExpansion ::regex "!CR!*!LF!" will match both Unix and Windows style End-Of-Line findstr /n /r /c:"A!CR!*!LF!A" TEST.TXT
donne ces résultats
1:A 2:A 5:A
La recherche sur les sauts de ligne à l'aide de l'option / G: FILE est imprécise car la seule manière de faire correspondre
[
correspond à
[<0x0C>-!]
Remarque - les éléments ci-dessus sont des représentations symboliques du stream d'octets regex, car je ne peux pas représenter graphiquement les caractères.
Réponse continue dans la partie 2 ci-dessous ...
Réponse suite de la partie 1 ci – dessus – J’ai rencontré la limite de réponse de 30 000 caractères 🙁
Prise en charge des expressions régulières limitées (regex)
La prise en charge de FINDSTR pour les expressions régulières est extrêmement limitée. S’il ne figure pas dans la documentation d’aide, il n’est pas pris en charge.
Au-delà de cela, les expressions de regex sockets en charge sont implémentées de manière totalement non standard, de sorte que les résultats peuvent être différents, puis attendus provenant de quelque chose comme grep ou perl.
Regex Line Position anchors ^ et $
^
correspond au début du stream d’entrée ainsi qu’à toute position suivant immédiatement un
$
correspond à toute position précédant immédiatement un $
ne correspondra à aucune ligne dans un fichier texte de style Unix, et ne correspondra pas non plus à la dernière ligne d’un fichier texte Windows s’il manque le marqueur EOL de
Remarque – Comme indiqué précédemment, les entrées redirigées et redirigées vers FINDSTR peuvent avoir
ajouté qui ne figure pas dans la source. Évidemment, cela peut avoir un impact sur une recherche de regex utilisant $
.
Toute chaîne de recherche avec des caractères avant ^
ou après $
échouera toujours à trouver une correspondance.
Options de positionnement / B / E / X
Les options de position fonctionnent de la même manière que ^
et $
, sauf qu’elles fonctionnent également pour les chaînes de recherche littérale.
/ B fonctionne de la même manière que ^
au début d’une chaîne de recherche de regex.
/ E fonctionne de la même manière que $
à la fin d’une chaîne de recherche de regex.
/ X fonctionne de la même manière que d’avoir les deux ^
au début et $
à la fin d’une chaîne de recherche de regex.
Limite du mot regex
\<
doit être le tout premier terme de l'expression rationnelle. Le regex ne correspondra à rien si d'autres caractères le précèdent. \<
correspond soit au tout début de l'entrée, au début d'une ligne (la position immédiatement après un
\>
doit être le tout dernier terme de la regex. Le regex ne correspondra à rien si d'autres personnages le suivent. \>
correspond soit à la fin de saisie, soit à la position précédant immédiatement un
Voici une liste complète des caractères "non-mot", représentés par le code d'octet décimal. Remarque - cette liste a été compilée sur une machine américaine. Je ne sais pas quel impact d'autres langues peuvent avoir sur cette liste.
001 028 063 179 204 230 002 029 064 180 205 231 003 030 091 181 206 232 004 031 092 182 207 233 005 032 093 183 208 234 006 033 094 184 209 235 007 034 096 185 210 236 008 035 123 186 211 237 009 036 124 187 212 238 011 037 125 188 213 239 012 038 126 189 214 240 014 039 127 190 215 241 015 040 155 191 216 242 016 041 156 192 217 243 017 042 157 193 218 244 018 043 158 194 219 245 019 044 168 195 220 246 020 045 169 196 221 247 021 046 170 197 222 248 022 047 173 198 223 249 023 058 174 199 224 250 024 059 175 200 226 251 025 060 176 201 227 254 026 061 177 202 228 255 027 062 178 203 229
Gammes de classes de caractères Regex [xy]
Les plages de classes de caractères ne fonctionnent pas comme prévu. Voir cette question: Pourquoi findstr ne gère-t-il pas le cas correctement (dans certaines circonstances)? , avec cette réponse: https://stackoverflow.com/a/8767815/1012053 .
Le problème est que FINDSTR ne comstack pas les caractères par leur valeur de code d'octet (généralement considéré comme le code ASCII, mais ASCII n'est défini qu'à partir de 0x00 - 0x7F). La plupart des implémentations de regex traiteraient [AZ] comme toutes les majuscules anglaises majuscules. Mais FINDSTR utilise une séquence de classement qui correspond à peu près au fonctionnement de SORT. Ainsi, [AZ] comprend l'alphabet anglais complet, majuscules et minuscules (sauf pour "a"), ainsi que des caractères alphabétiques non anglais avec diacritiques.
Vous trouverez ci-dessous une liste complète de tous les caractères pris en charge par FINDSTR, sortingés dans la séquence de classement utilisée par FINDSTR pour établir les plages de classes de caractères regex. Les caractères sont représentés par leur valeur de code décimal octet. Je crois que la séquence de classement a le plus de sens si les caractères sont visualisés avec la page de code 437. Remarque: cette liste a été compilée sur une machine américaine. Je ne sais pas quel impact d'autres langues peuvent avoir sur cette liste.
001 002 003 004 005 006 007 008 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 127 039 045 032 255 009 010 011 012 013 033 034 035 036 037 038 040 041 042 044 046 047 058 059 063 064 091 092 093 094 095 096 123 124 125 126 173 168 155 156 157 158 043 249 060 061 062 241 174 175 246 251 239 247 240 243 242 169 244 245 254 196 205 179 186 218 213 214 201 191 184 183 187 192 212 211 200 217 190 189 188 195 198 199 204 180 181 182 185 194 209 210 203 193 207 208 202 197 216 215 206 223 220 221 222 219 176 177 178 170 248 230 250 048 172 171 049 050 253 051 052 053 054 055 056 057 236 097 065 166 160 133 131 132 142 134 143 145 146 098 066 099 067 135 128 100 068 101 069 130 144 138 136 137 102 070 159 103 071 104 072 105 073 161 141 140 139 106 074 107 075 108 076 109 077 110 252 078 164 165 111 079 167 162 149 147 148 153 112 080 113 081 114 082 115 083 225 116 084 117 085 163 151 150 129 154 118 086 119 087 120 088 121 089 152 122 090 224 226 235 238 233 227 229 228 231 237 232 234
Limite de terme de la classe de caractères Regex et BUG
FINDSTR est non seulement limité à un maximum de 15 termes de classe de caractères dans une expression régulière, mais il ne parvient pas à gérer correctement une tentative de dépassement de la limite. L'utilisation de 16 termes de classe de caractères ou plus se traduit par une fenêtre pop-up Windows interactive indiquant que «l'utilitaire Find Ssortingng (QGREP) a rencontré un problème et doit être fermé. Nous sums désolés pour le désagrément». Le texte du message varie légèrement selon la version de Windows. Voici un exemple de FINDSTR qui échouera:
echo 01234567890123456|findstr [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
Ce bug a été signalé par l'utilisateur Judos de DosTips ici . Il a été confirmé sur XP, Vista et Windows 7.
Les recherches d'expressions rationnelles échouent (et peuvent se bloquer indéfiniment) si elles incluent le code d'octet 0xFF (décimal 255)
Toute recherche de regex qui inclut le code d'octet 0xFF (décimal 255) échouera. Il échoue si le code d'octet 0xFF est inclus directement ou s'il est implicitement inclus dans une plage de classes de caractères. Remember that FINDSTR character class ranges do not collate characters based on the byte code value. Character <0xFF>
appears relatively early in the collation sequence between the
and
characters. So any character class range that includes both
and
will fail.
The exact behavior changes slightly depending on the Windows version. Windows 7 hangs indefinitely if 0xFF is included. XP doesn't hang, but it always fails to find a match, and occasionally prints the following error message - "The process sortinged to write to a nonexistent pipe."
I no longer have access to a Vista machine, so I haven't been able to test on Vista.
Regex bug: .
and [^anySet]
can match End-Of-File
The regex .
meta-character should only match any character other than
or
. There is a bug that allows it to match the End-Of-File if the last line in the file is not terminated by
or
. However, the .
will not match an empty file.
For example, a file named "test.txt" containing a single line of x
, without terminating
or
, will match the following:
findstr /r x......... test.txt
This bug has been confirmed on XP and Win7.
The same seems to be true for negative character sets. Something like [^abc]
will match End-Of-File. Positive character sets like [abc]
seem to work fine. I have only tested this on Win7.
findstr
sometimes hangs unexpectedly when searching large files.
I haven’t confirmed the exact conditions or boundary sizes. I suspect any file larger 2GB may be at risk.
I have had mixed experiences with this, so it is more than just file size. This looks like it may be a variation on FINDSTR hangs on XP and Windows 7 if redirected input does not end with LF , but as demonstrated this particular problem manifests when input is not redirected.
The following command line session (Windows 7) demonstrates how findstr
can hang when searching a 3GB file.
C:\Data\Temp\2014-04>echo 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890> T100B.txt C:\Data\Temp\2014-04>for /L %i in (1,1,10) do @type T100B.txt >> T1KB.txt C:\Data\Temp\2014-04>for /L %i in (1,1,1000) do @type T1KB.txt >> T1MB.txt C:\Data\Temp\2014-04>for /L %i in (1,1,1000) do @type T1MB.txt >> T1GB.txt C:\Data\Temp\2014-04>echo find this line>> T1GB.txt C:\Data\Temp\2014-04>copy T1GB.txt + T1GB.txt + T1GB.txt T3GB.txt T1GB.txt T1GB.txt T1GB.txt 1 file(s) copied. C:\Data\Temp\2014-04>dir Volume in drive C has no label. Volume Serial Number is D2B2-FFDF Directory of C:\Data\Temp\2014-04 2014/04/08 04:28 PM . 2014/04/08 04:28 PM .. 2014/04/08 04:22 PM 102 T100B.txt 2014/04/08 04:28 PM 1 020 000 016 T1GB.txt 2014/04/08 04:23 PM 1 020 T1KB.txt 2014/04/08 04:23 PM 1 020 000 T1MB.txt 2014/04/08 04:29 PM 3 060 000 049 T3GB.txt 5 File(s) 4 081 021 187 bytes 2 Dir(s) 51 881 050 112 bytes free C:\Data\Temp\2014-04>rem Findstr on the 1GB file does not hang C:\Data\Temp\2014-04>findstr "this" T1GB.txt find this line C:\Data\Temp\2014-04>rem On the 3GB file, findstr hangs and must be aborted... even though it clearly reaches end of file C:\Data\Temp\2014-04>findstr "this" T3GB.txt find this line find this line find this line ^C C:\Data\Temp\2014-04>
Note, I’ve verified in a hex editor that all lines are terminated with CRLF
. The only anomaly is that the file is terminated with 0x1A
due to the way copy
works . Note however, that this anomaly doesn’t cause a problem on “small” files .
With additional testing I have confirmed the following:
copy
with the /b
option for binary files prevents the addition of the 0x1A
character, and findstr
doesn’t hang on the 3GB file. findstr
to hang. 0x1A
character doesn’t cause any problems on a “small” file. (Similarly for other terminating characters.) CRLF
after 0x1A
resolves the problem. ( LF
by itself would probably suffice.) type
to pipe the file into findstr
works without hanging. (This might be due to a side effect of either type
or |
that inserts an additional End Of Line.) <
also causes findstr
to hang. But this is expected; as explained in dbenham's post : "redirected input must end in LF
" . When several commands are enclosed in parentheses and there are redirected files to the whole block:
< input.txt ( command1 command2 . . . ) > output.txt
… then the files remains open as long as the commands in the block be active, so the commands may move the file pointer of the redirected files. Both MORE and FIND commands move the Stdin file pointer to the beginning of the file before process it, so the same file may be processed several times inside the block. For example, this code:
more < input.txt > output.txt more < input.txt >> output.txt
… produce the same result than this one:
< input.txt ( more more ) > output.txt
Ce code:
find "search ssortingng" < input.txt > matchedLines.txt find /V "search ssortingng" < input.txt > unmatchedLines.txt
… produce the same result than this one:
< input.txt ( find "search string" > matchedLines.txt find /V "search ssortingng" > unmatchedLines.txt )
FINDSTR is different; it does not move the Stdin file pointer from its current position. For example, this code insert a new line after a search line:
call :ProcessFile < input.txt goto :EOF :ProcessFile rem Read the next line from Stdin and copy it set /P line= echo %line% rem Test if it is the search line if "%line%" neq "search line" goto ProcessFile rem Insert the new line at this point echo New line rem And copy the rest of lines findstr "^" exit /B
We may make good use of this feature with the aid of an auxiliary program that allow us to move the file pointer of a redirected file, as shown in this example .
This behavior was first reported by jeb at this post .
EDIT 2018-08-18 : New FINDSTR bug reported
The FINDSTR command have a strange bug that happen when this command is used to show characters in color AND the output of such a command is redirected to CON device. For details on how use FINDSTR command to show text in color, see this topic .
When the output of this form of FINDSTR command is redirected to CON, something strange happens after the text is output in the desired color: all the text after it is output as "invisible" characters, although a more precise description is that the text is output as black text over black background. The original text will appear if you use COLOR command to reset the foreground and background colors of the entire screen. However, when the text is "invisible" we could execute a SET /P command, so all characters entered will not appear on the screen. This behavior may be used to enter passwords.
@echo off setlocal set /P "=_" < NUL > "Enter password" findstr /A:1E /V "^$" "Enter password" NUL > CON del "Enter password" set /P "password=" cls color 07 echo The password read is: "%password%"
I’d like to report a bug regarding the section Source of data to search in the first answer when using en dash (–) or em dash (—) within the filename.
More specifically, if you are about to use the first option – filenames specified as arguments , the file won’t be found. As soon as you use either option 2 – stdin via redirection or 3 – data stream from a pipe , findstr will find the file.
For example, this simple batch script:
echo off chcp 1250 > nul set INTEXTFILE1=filename with – dash.txt set INTEXTFILE2=filename with — dash.txt rem 3 way of findstr use with en dashed filename echo. echo Filename with en dash: echo. echo 1. As argument findstr . "%INTEXTFILE1%" echo. echo 2. As stdin via redirection findstr . < "%INTEXTFILE1%" echo. echo 3. As datastream from a pipe type "%INTEXTFILE1%" | findstr . echo. echo. rem The same set of operations with em dashed filename echo Filename with em dash: echo. echo 1. As argument findstr . "%INTEXTFILE2%" echo. echo 2. As stdin via redirection findstr . < "%INTEXTFILE2%" echo. echo 3. As datastream from a pipe type "%INTEXTFILE2%" | findstr . echo. pause
imprimera:
Filename with en dash:
As argument
FINDSTR: Cannot open filename with - dash.txt
As stdin via redirection
I am the file with an en dash.
As datastream from a pipe
I am the file with an en dash.
Filename with em dash:
As argument
FINDSTR: Cannot open filename with - dash.txt
As stdin via redirection
I am the file with an em dash.
As datastream from a pipe
I am the file with an em dash.
J'espère que cela aide.
M.
/D tip for multiple directories: put your directory list before the search ssortingng. These all work:
findstr /D:dir1;dir2 "searchSsortingng" *.* findstr /D:"dir1;dir2" "searchSsortingng" *.* findstr /D:"\path\dir1\;\path\dir2\" "searchSsortingng" *.*
As expected, the path is relative to location if you don’t start the directories with \
. Surrounding the path with "
is optional if there are no spaces in the directory names. The ending \
is optional. The output of location will include whatever path you give it. It will work with or without surrounding the directory list with "
.