La commande Windows FINDSTR est horriblement documentée. Une aide de ligne de commande très basique est disponible via FINDSTR /?
ou HELP FINDSTR
, mais elle est malheureusement insuffisante. Il existe un tout petit peu plus de documentation en ligne à l' adresse https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr .
Il existe de nombreuses fonctionnalités et limitations de FINDSTR qui ne sont même pas mentionnées dans la documentation. Ils ne pourraient pas non plus être anticipés sans connaissance préalable et / ou expérimentation minutieuse.
La question est donc: quelles sont les fonctionnalités et 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 profiter pleinement des fonctionnalités disponibles.
B) Les développeurs ne perdent pas leur temps à se demander pourquoi quelque chose ne fonctionne pas alors que cela semble normal.
Veuillez vous assurer que vous connaissez la documentation existante avant de répondre. Si les informations sont couvertes par l'AIDE, elles n'appartiennent 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 sur la base de la documentation, alors cela n'a pas sa place ici.
Dans le même ordre d'idées, si une personne logique pouvait anticiper le comportement d'un usage particulier sur la base d'informations contenues dans des réponses existantes, alors encore une fois, cela n'a pas sa place ici.
la source
grep
qui est très bien compris et documenté :-) Voir stackoverflow.com/questions/2635740/… par exemple.Réponses:
Préface La
plupart des informations contenues dans cette réponse ont été recueillies sur la base d'expériences exécutées sur une machine Vista. Sauf indication contraire explicite, je n'ai pas confirmé si les informations s'appliquent à d'autres versions de Windows.
Sortie FINDSTR
La documentation ne se soucie jamais d'expliquer la sortie de FINDSTR. Cela fait allusion au fait que les lignes correspondantes sont imprimées, mais rien de plus.
Le format de la sortie de ligne correspondante est le suivant:
nom de fichier: lineNumber: lineOffset: texte
où
fileName: = Le nom du fichier contenant la ligne correspondante. Le nom du fichier n'est pas imprimé si la demande concernait explicitement un seul fichier, ou si la recherche d'une entrée canalisée ou d'une entrée redirigée. Une fois imprimé, le fileName inclura toujours toutes les informations de chemin fournies. Des informations de chemin supplémentaires seront ajoutées si l'
/S
option est utilisée. Le chemin imprimé est toujours relatif au chemin fourni, ou relatif au répertoire courant 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 mal documentés)
<
et>
. Les règles exactes du 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 ligne de la ligne correspondante représentée sous forme de valeur décimale avec 1 représentant la 1ère ligne de l'entrée. Imprimé uniquement si l'
/N
option est spécifiée.lineOffset: = Le décalage d'octet décimal du début de la ligne correspondante, 0 représentant le 1er caractère de la 1ère ligne. Imprimé uniquement si l'
/O
option est spécifiée. Ce n'est pas le décalage de la correspondance dans la ligne. C'est le nombre d'octets entre le début du fichier et le début de la ligne.text = La représentation binaire de la ligne correspondante, y compris tout <CR> et / ou <LF>. Rien n'est laissé en dehors de la sortie binaire, de sorte que cet exemple qui correspond à toutes les lignes produira une copie binaire exacte du fichier d'origine.
L'option / A définit la couleur du fileName :, lineNumber: et lineOffset: sortie uniquement. Le texte de la ligne correspondante est toujours affiché avec la couleur actuelle de la console. L'option / A n'a d'effet que lorsque la sortie est affichée directement sur la console. L'option / A n'a aucun effet si la sortie est redirigée vers un fichier ou redirigée. Voir la modification du 18/08/2018 dans la réponse d' Aacini pour une description du comportement bogué lorsque la sortie est redirigée vers CON.
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 comme eux-mêmes: 0x09 Tab, 0x0A LineFeed, 0x0B Vertical Tab, 0x0C Form Feed, 0x0D Carriage Return.
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 qui sont transformés lorsqu'ils sont fournis sur la ligne de commande. Voir la section «Limites de caractères pour les paramètres de ligne de commande - Transformation ASCII étendue» , plus loin dans cet article
Les caractères de contrôle et l'ASCII étendu 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 comme eux-mêmes, jamais sous forme de points.
Codes de retour (ERRORLEVEL)
/A:xx
option/L
et les/R
deux spécifiées/A:
,/F:
,/C:
,/D:
ou/G:
/F:file
ou/G:file
introuvablevoir limite de terme de classe de caractère Regex et BUG dans la partie 2 de la réponse
Source des données à rechercher (mise à jour en fonction de tests avec 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'
/F:file
option.stdin via la redirection
findstr "searchString" <file
flux de données depuis un tube
type file | findstr "searchString"
Les arguments / options ont priorité sur la redirection, qui a la priorité sur les données acheminées.
Arguments de nom de fichier et
/F:file
peuvent être combinés. Plusieurs arguments de nom de fichier peuvent être utilisés. Si plusieurs/F:file
options sont spécifiées, seule la dernière est utilisée. Les caractères génériques sont autorisés dans les arguments de nom de fichier, mais pas dans le fichier pointé par/F:file
.Source des chaînes de recherche (mise à jour basée sur des tests avec Windows 7)
Les options
/G:file
et/C:string
peuvent être combinées. Plusieurs/C:string
options peuvent être spécifiées. Si plusieurs/G:file
options sont spécifiées, seule la dernière est utilisée. Si l'un/G:file
ou l' autre/C:string
est utilisé, tous les arguments sans option sont supposés être des fichiers à rechercher. Si ni/G:file
ni/C:string
n'est utilisé, alors le premier argument sans option est traité comme une liste délimitée par des espaces de termes de recherche.Les noms de fichiers ne doivent pas être cités dans le fichier lors de l'utilisation de l'
/F:FILE
option.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'
/F:files.txt
option FINDSTR exige que les noms de fichiers dans files.txt ne soient PAS entre guillemets. Le fichier ne sera pas trouvé si le nom est cité.BOGUE - Les noms de fichiers 8.3 courts peuvent casser les options
/D
et/S
Comme avec toutes les commandes Windows, FINDSTR tentera de faire correspondre à la fois le nom long et le nom court 8.3 lors de la recherche de fichiers à rechercher. Supposons que le dossier actuel contient les fichiers non vides suivants:
La commande suivante trouvera avec succès les 3 fichiers:
b.txt2
correspond car le nom court correspondantB9F64~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
fait que les commandes suivantes ne trouvent queb1.txt
Le bogue empêche
b.txt2
d'être trouvé, ainsi que tous les noms de fichiers qui trient aprèsb.txt2
dans le même répertoire. Des fichiers supplémentaires qui sont triés avant, commea.txt
, sont trouvés. Des fichiers supplémentaires qui sont triés plus tard, commed.txt
, sont manqués une fois le bogue déclenché.Chaque répertoire recherché est traité indépendamment. Par exemple, l'
/S
option commencerait avec succès la recherche dans un dossier enfant après avoir échoué à trouver des fichiers dans le parent, mais une fois que le bogue ferait manquer un nom de fichier court à l'enfant, tous les fichiers suivants dans ce dossier enfant seraient également manqués .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é, maisc.txt
serait trouvé correctement.Tous les noms courts ne déclenchent pas le bogue. Toutes les instances de comportement bogué que j'ai vues impliquent une extension de plus de 3 caractères avec un nom court 8.3 qui commence de la même manière qu'un nom normal qui ne nécessite pas un nom 8.3.
Le bogue a été confirmé sur XP, Vista et Windows 7.
Caractères non imprimables et
/P
optionL'
/P
option oblige FINDSTR à ignorer tout fichier contenant l'un des codes d'octets décimaux suivants:0-7, 14-25, 27-31.
En d'autres termes, l'
/P
option ignorera 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:Tous les autres caractères de contrôle sont traités comme non imprimables, dont la présence fait que l'
/P
option ignore le fichier.L'entrée canalisée et redirigée peut avoir été
<CR><LF>
ajoutéeSi l'entrée est canalisée et que le dernier caractère du flux ne l'est pas
<LF>
, alors FINDSTR s'ajoutera automatiquement<CR><LF>
à l'entrée. Cela a été confirmé sur XP, Vista et Windows 7. (J'avais l'habitude de penser que le canal 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.)Il en va de même pour les entrées redirigées sur Vista. Si le dernier caractère d'un fichier utilisé comme entrée redirigée ne l'est pas
<LF>
, FINDSTR s'ajoutera automatiquement<CR><LF>
à l'entrée. Cependant, XP et Windows 7 ne modifient pas l'entrée redirigée.FINDSTR se bloque sur XP et Windows 7 si l'entrée redirigée ne se termine pas par
<LF>
Ceci 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
<LF>
, alors FINDSTR se bloquera indéfiniment une fois qu'il atteint la fin du fichier redirigé.La dernière ligne de données Piped peut être ignorée si elle se compose d'un seul caractère.
Si l'entrée est redirigée et que la dernière ligne se compose d'un seul caractère qui n'est pas suivi de
<LF>
, FINDSTR ignore complètement la dernière ligne.Exemple - La première commande avec un seul caractère et non
<LF>
ne correspond pas, mais la deuxième commande avec 2 caractères fonctionne bien, tout comme la troisième commande qui a un caractère avec une nouvelle ligne de fin.Rapporté par l'utilisateur de DosTips Sponge Belly au nouveau bug de 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 des
options Les lettres des options ne sont pas sensibles à la casse
/i
et/I
sont donc équivalentes.Les options peuvent être préfixées avec l'un
/
ou l' autre ou Les-
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 à plusieurs caractères telle que OFF ou F :, et l'option à plusieurs caractères doit être la dernière option de la liste.Ce qui suit sont toutes des manières équivalentes d'exprimer une recherche regex insensible à la casse pour toute ligne contenant à la fois «bonjour» 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"
Des options peuvent également être citées. Alors
/i
,-i
,"/i"
et"-i"
sont tous équivalents. De même,/c:string
,"/c":string
,"/c:"string
et"/c:string"
sont tous équivalents.Si une chaîne de recherche commence par un littéral
/
ou-
, l' option/C
ou/G
doit être utilisée. Merci à Stephan d' avoir signalé cela dans un commentaire (supprimé depuis).Limites de longueur de chaîne de recherche
Sous 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 string too long.
erreur avec ERRORLEVEL 2.Lors d'une recherche d'expression régulière, la longueur maximale de la chaîne de recherche est de 254. Une expression régulière d'une longueur comprise entre 255 et 511 entraînera une
FINDSTR: Out of memory
erreur avec ERRORLEVEL 2. Une longueur d'expression régulière> 511 entraîne l'FINDSTR: Search string too long.
erreur.Sous 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 la sous-chaîne dans la boucle "for"? La limite XP est de 127 octets pour les recherches littérales et regex.
Limites de longueur de ligne Les
fichiers spécifiés comme argument de ligne de commande ou via l'option / F: FILE n'ont pas de 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 <LF>.
Les données canalisées et l'entrée redirigée sont limitées à 8191 octets par ligne. Cette limite est une "fonctionnalité" de FINDSTR. Il 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 jamais à une ligne supérieure à 8 ko. Les lignes> = 8k génèrent un message d'erreur à stderr, mais ERRORLEVEL est toujours égal à 0 si la chaîne de recherche se trouve dans au moins une ligne d'au moins un fichier.
Type de recherche par défaut: Literal vs Regular Expression
/C:"string"
- La valeur par défaut est / L literal. Combiner explicitement l'option / L avec / C: "string" fonctionne certes mais est redondant."string argument"
- La valeur par défaut dépend du contenu de la toute première chaîne de recherche. (N'oubliez pas que <space> est utilisé pour délimiter les chaînes de recherche.) Si la première chaîne de recherche est une expression régulière valide qui contient 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. Par exemple,"51.4 200"
sera traitée comme deux expressions régulières car la première chaîne contient un point non échappé, alors"200 51.4"
qu'elle sera traitée 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 - Spécifiez toujours explicitement
/L
l'option littérale ou l'/R
option d'expression régulière lorsque vous utilisez"string argument"
ou/G:file
.BOGUE - La spécification de plusieurs chaînes de recherche littérales peut donner des résultats peu fiables
L'exemple simple FINDSTR suivant ne parvient pas à trouver une correspondance, même s'il le devrait.
Ce bogue a été confirmé sur Windows Server 2003, Windows XP, Vista et Windows 7.
D'après des expériences, FINDSTR peut échouer si toutes les conditions suivantes sont remplies:
/I
option)Dans chaque échec que j'ai vu, c'est toujours l'une des chaînes de recherche les plus courtes qui échoue.
Pour plus d'informations, consultez Pourquoi cet exemple FINDSTR avec plusieurs chaînes de recherche littérales ne trouve-t-il pas une correspondance?
Échapper les
guillemets et les barres obliques inverses dans / G: FILE chaînes de recherche littérales Citations et barres obliques inverses autonomes dans un fichier de chaîne de recherche littérale spécifié par / G: le fichier n'a pas besoin d'être échappé, mais ils peuvent l'être.
"
et\"
sont équivalents.\
et\\
sont équivalents.Si l'intention est de trouver \\, au moins la barre oblique inverse de début doit être échappée. Les deux
\\\
et\\\\
travailler.Si l'intention est de trouver ", au moins la barre oblique inverse de début doit être échappée. Les deux
\\"
et\\\"
fonctionnent.Échappement de Quote et Backslash dans / G: FILE chaînes de recherche de regex
C'est le seul cas où les séquences d'échappement fonctionnent comme prévu d'après la documentation. Quote n'est pas un métacaractère regex, il n'a donc pas besoin d'être échappé (mais peut l'être). Backslash est un métacaractère regex, il doit donc être échappé.
Limites de caractères pour les paramètres 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 à un octet peut apparaître dans la chaîne (0x01 - 0xFF). Cependant, FINDSTR convertit de nombreux caractères ASCII étendus qu'il trouve dans les paramètres de ligne de commande en d'autres caractères. Cela a un impact majeur de deux manières:
De nombreux caractères ASCII étendus ne correspondent 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 regex. Si une chaîne de recherche doit contenir de l'ASCII étendu, l'
/G:FILE
option doit être utilisée à la place.FINDSTR peut ne pas trouver un fichier si le nom contient des caractères ASCII étendus et que le nom du fichier est spécifié sur la ligne de commande. Si un fichier à rechercher contient de l'ASCII étendu dans le nom, l'
/F:FILE
option doit être utilisée à la place.Voici une liste complète des transformations de caractères ASCII étendues que FINDSTR effectue sur les chaînes de ligne de commande. Chaque caractère est représenté comme la valeur de code d'octet décimal. Le premier code représente le caractère tel qu'il est fourni sur la ligne de commande et le deuxième 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.
Tout caractère> 0 ne figurant pas dans la liste ci-dessus est traité comme lui-même, y compris
<CR>
et <LF>
. Le moyen le plus simple d'inclure des caractères impairs comme<CR>
et<LF>
est de les placer dans une variable d'environnement et d'utiliser l'expansion retardée dans l'argument de 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 se trouvaient sur une autre ligne.
Les caractères
<CR>
et<LF>
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 pas rechercher d'octets nuls et Unicode contient généralement de nombreux octets nuls.
Cependant, la commande TYPE convertit UTF-16LE avec BOM en un jeu de caractères à un octet, donc une commande comme celle-ci fonctionnera avec UTF-16LE avec BOM.
Notez que les points de code Unicode qui ne sont pas pris en charge par votre page de codes active seront convertis en
?
caractères.Il est possible de rechercher UTF-8 tant que votre chaîne de recherche ne contient que de l'ASCII. Cependant, la sortie de console de tout caractère UTF-8 multi-octets 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, alors la nomenclature sera considérée comme faisant partie de la première ligne, ce qui pourrait annuler une recherche qui correspond au début d'une ligne.
Il est possible de rechercher des caractères UTF-8 multi-octets si vous placez votre chaîne de recherche dans un fichier de recherche encodé en UTF-8 (sans BOM) et utilisez l'option / G.
Fin de ligne
FINDSTR coupe les lignes immédiatement après chaque <LF>. La présence ou l'absence de <CR> n'a aucun impact sur les sauts de ligne.
Recherche à travers les sauts de ligne
Comme prévu, le
.
métacaractère regex ne correspondra pas à <CR> ou <LF>. Mais il est possible d'effectuer une recherche sur un saut de ligne à l'aide d'une chaîne de recherche en ligne de commande. Les caractères <CR> et <LF> doivent être mis en correspondance explicitement. Si une correspondance multiligne est trouvée, seule la 1ère ligne de la correspondance est imprimée. FINDSTR revient ensuite à la deuxième ligne de la source et recommence la recherche - une sorte de fonction de type «regarder en avant».Supposons que TEXT.TXT a ce contenu (peut être de style Unix ou Windows)
Puis ce script
donne ces résultats
La recherche à travers les sauts de ligne à l'aide de l'option / G: FILE est imprécise car le seul moyen de faire correspondre <CR> ou <LF> est via une expression de plage de classe de caractères regex qui prend en sandwich les caractères EOL.
[<TAB>-<0x0B>]
correspond à <LF>, mais correspond également à <TAB> et <0x0B>[<0x0C>-!]
correspond à <CR>, mais aussi à <0x0C> et!Remarque - ce qui précède sont des représentations symboliques du flux d'octets regex car je ne peux pas représenter graphiquement les caractères.
Réponse suite à la partie 2 ci-dessous ...
la source
addpath.bat
de Q141344 et findstr, qui peut être lié au problème de blocage de Win7 mentionné ci-dessus. J'ai créé une salle de chat pour essayer de retracer cela, pour tous ceux qui sont intéressés: chat.stackoverflow.com/rooms/13177/…/S
et des/D
options provenant de noms de fichiers 8.3 courts.<LF>
Réponse suite de la partie 1 ci - dessus - J'ai rencontré la limite de réponse de 30000 caractères :-(
Prise en
charge limitée des expressions régulières (regex) La prise en charge par FINDSTR des expressions régulières est extrêmement limitée. S'il ne figure pas dans la documentation HELP, il n'est pas pris en charge.
Au-delà de cela, les expressions regex prises en charge sont implémentées de manière totalement non standard, de sorte que les résultats peuvent être différents de ceux attendus de quelque chose comme grep ou perl.
Les ancres de position de ligne d'expression régulière ^ et $
^
correspondent au début du flux d'entrée ainsi qu'à toute position suivant immédiatement un <LF>. Puisque FINDSTR coupe également les lignes après <LF>, une simple expression régulière de "^" correspondra toujours à toutes les lignes d'un fichier, même un fichier binaire.$
correspond à n'importe quelle position précédant immédiatement un <CR>. Cela signifie qu'une chaîne de recherche regex contenant$
ne correspondra jamais à aucune ligne dans un fichier texte de style Unix, ni à la dernière ligne d'un fichier texte Windows s'il manque le marqueur EOL de <CR> <LF>.Remarque - Comme indiqué précédemment, des entrées canalisées et redirigées vers FINDSTR peuvent avoir été
<CR><LF>
ajoutées qui ne sont pas dans la source. Évidemment, cela peut avoir un impact sur une recherche regex qui utilise$
.Toute chaîne de recherche avec des caractères avant
^
ou après$
échouera toujours à trouver une correspondance.Options de position / 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érales./ B fonctionne de la même manière
^
qu'au début d'une chaîne de recherche regex./ E fonctionne de la même manière
$
qu'à la fin d'une chaîne de recherche regex./ X fonctionne de la même manière que d'avoir
^
à la fois au début et$
à la fin d'une chaîne de recherche regex.La limite du mot Regex
\<
doit être le tout premier terme de l'expression régulière. 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 <LF>), soit à la position immédiatement après tout caractère "non-mot". Le caractère suivant n'a pas besoin d'être un caractère "mot".\>
doit être le tout dernier terme de l'expression régulière. Le regex ne correspondra à rien si d'autres caractères le suivent.\>
correspond soit à la fin de l'entrée, soit à la position immédiatement avant un <CR>, soit à la position précédant immédiatement tout caractère "non-mot". Le caractère précédent n'a pas besoin d'être un caractère "mot".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.
Plages 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 correctement la casse (dans certaines circonstances)? , avec cette réponse: https://stackoverflow.com/a/8767815/1012053 .
Le problème est que FINDSTR ne rassemble 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 que 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, en majuscules et minuscules (sauf pour "a"), ainsi que les caractères alpha non anglais avec des signes diacritiques.
Vous trouverez ci-dessous une liste complète de tous les caractères pris en charge par FINDSTR, triés dans la séquence de classement utilisée par FINDSTR pour établir des plages de classes de caractères regex. Les caractères sont représentés par leur valeur de code d'octet décimal. Je pense que la séquence de classement a le plus de sens si les caractères sont affichés à l'aide de la page de codes 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.
Limite de termes de classe de caractères Regex et BUG
Non seulement FINDSTR est 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 termes de classe de 16 caractères ou plus entraîne une fenêtre contextuelle Windows interactive indiquant "L'utilitaire de recherche de chaîne (QGREP) a rencontré un problème et doit fermer. Nous sommes 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:
Ce bug a été signalé par l' utilisateur DosTips Judago ici . Il a été confirmé sur XP, Vista et Windows 7.
Les recherches regex échouent (et peuvent se bloquer indéfiniment) si elles incluent le code d'octet 0xFF (décimal 255) Toute recherche d'expression régulière 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. N'oubliez pas que les plages de classes de caractères FINDSTR ne rassemblent pas les caractères en fonction de la valeur du code d'octet. Le caractère
<0xFF>
apparaît relativement tôt dans la séquence de classement entre les caractères<space>
et<tab>
. Donc, toute plage de classes de caractères qui inclut les deux<space>
et<tab>
échouera.Le comportement exact change légèrement selon la version de Windows. Windows 7 se bloque indéfiniment si 0xFF est inclus. XP ne se bloque pas, mais il ne parvient toujours pas à trouver une correspondance et imprime parfois le message d'erreur suivant - "Le processus a essayé d'écrire dans un tube inexistant."
Je n'ai plus accès à une machine Vista, donc je n'ai pas pu tester sur Vista.
Bug Regex:
.
et[^anySet]
peut correspondre à End-Of-FileLe
.
méta-caractère regex ne doit correspondre qu'à n'importe quel caractère autre que<CR>
ou<LF>
. Il existe un bogue qui lui permet de correspondre à la fin du fichier si la dernière ligne du fichier ne se termine pas par<CR>
ou<LF>
. Cependant, le.
ne correspondra pas à un fichier vide.Par exemple, un fichier nommé "test.txt" contenant une seule ligne de
x
, sans terminer<CR>
ou<LF>
, correspondra à ce qui suit:Ce bogue a été confirmé sur XP et Win7.
La même chose semble être vraie pour les jeux de caractères négatifs. Quelque chose comme
[^abc]
cela correspondra à la fin du fichier. Les jeux de caractères positifs[abc]
semblent fonctionner correctement. Je n'ai testé cela que sur Win7.la source
type
dansfindstr
.findstr
prend en charge plusieurs/c:
chaînes de recherche. Je sais que vos réponses le démontrent. Mais c'est quelque chose qui n'est pas documenté; et j'ai été assez surpris d'apprendre la fonctionnalité après l'avoir utiliséefindstr
sans elle pendant quelques années.LF
problème que vous avez documenté. J'ai réalisé que mon fichier de test ne se terminait pasLF
parce que je l'ai utilisécopy
en mode ajout pour le créer. J'ai mis une session de ligne de commande pour démontrer le problème dans une réponse ( stackoverflow.com/a/22943056/224704 ). Notez que l'entrée n'est pas redirigée, et pourtant la recherche se bloque. La même commande de recherche ne se bloque pas avec des fichiers plus petits qui ne se terminent pas non plus parLF
.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 classes de caractères) -ErrorLevel = -1073740791 (0xC0000409)
, la fenêtre de dialogue d'erreur :Find String (QGREP) Utility has stopped working
; après avoir supprimé une classe ou deux méta caractères (*\.
), ça marche ...findstr
se bloque parfois de manière inattendue lors de la recherche de fichiers volumineux.Je n'ai pas confirmé les conditions exactes ou les tailles des limites. Je soupçonne que tout fichier de plus de 2 Go peut être à risque.
J'ai eu des expériences mitigées avec cela, donc c'est plus que juste la taille du fichier. Cela semble être une variante de FINDSTR se bloque sur XP et Windows 7 si l'entrée redirigée ne se termine pas par LF , mais comme démontré, ce problème particulier se manifeste lorsque l'entrée n'est pas redirigée.
La session de ligne de commande suivante (Windows 7) montre comment
findstr
se bloquer lors de la recherche d'un fichier de 3 Go.Remarque, j'ai vérifié dans un éditeur hexadécimal que toutes les lignes se terminent par
CRLF
. La seule anomalie est que le fichier se termine en0x1A
raison de la façon dontcopy
fonctionne . Notez cependant que cette anomalie ne pose pas de problème sur les "petits" fichiers .Avec des tests supplémentaires, j'ai confirmé ce qui suit:
copy
avec l'/b
option pour les fichiers binaires empêche l'ajout du0x1A
caractère etfindstr
ne se bloque pas sur le fichier de 3 Go.findstr
blocage d'un.0x1A
caractère ne pose aucun problème sur un "petit" fichier. (De même pour les autres caractères de fin.)CRLF
après0x1A
résout le problème. (LF
en soi suffirait probablement.)type
pour diriger le fichier dans desfindstr
œuvres sans accrocher. (Cela peut être dû à un effet secondaire de l'untype
ou l' autre ou|
qui insère une fin de ligne supplémentaire.)<
provoque également unfindstr
blocage. Mais cela est attendu; comme expliqué dans le post de dbenham : "l'entrée redirigée doit se terminer parLF
" .la source
<LF>
. Un fichier de deux octets plus petit ne s'est pas bloqué. Très sale!Lorsque plusieurs commandes sont placées entre parenthèses et qu'il y a des fichiers redirigés vers le bloc entier:
... alors les fichiers restent ouverts tant que les commandes du bloc sont actives, de sorte que les commandes peuvent déplacer le pointeur de fichier des fichiers redirigés. Les commandes MORE et FIND déplacent le pointeur de fichier Stdin au début du fichier avant de le traiter, de sorte que le même fichier peut être traité plusieurs fois à l'intérieur du bloc. Par exemple, ce code:
... produisent le même résultat que celui-ci:
Ce code:
... produisent le même résultat que celui-ci:
FINDSTR est différent; il ne déplace pas le pointeur de fichier Stdin de sa position actuelle. Par exemple, ce code insère une nouvelle ligne après une ligne de recherche:
Nous pouvons faire bon usage de cette fonctionnalité à l'aide d'un programme auxiliaire qui nous permet de déplacer le pointeur de fichier d'un fichier redirigé, comme indiqué dans cet exemple .
Ce comportement a été signalé pour la première fois par jeb à ce poste .
EDIT 2018-08-18 : Nouveau bogue FINDSTR signalé
La commande FINDSTR a un bogue étrange qui se produit lorsque cette commande est utilisée pour afficher des caractères en couleur ET que la sortie d'une telle commande est redirigée vers le périphérique CON. Pour plus d'informations sur l'utilisation de la commande FINDSTR pour afficher le texte en couleur, consultez cette rubrique .
Lorsque la sortie de cette forme de commande FINDSTR est redirigée vers CON, quelque chose d'étrange se produit après la sortie du texte dans la couleur désirée: tout le texte après qu'il est sorti en tant que caractères "invisibles", bien qu'une description plus précise soit que le texte est sortie sous forme de texte noir sur fond noir. Le texte d'origine apparaîtra si vous utilisez la commande COULEUR pour réinitialiser les couleurs de premier plan et d'arrière-plan de tout l'écran. Cependant, lorsque le texte est «invisible», nous pouvons exécuter une commande SET / P, de sorte que tous les caractères saisis n'apparaissent pas à l'écran. Ce comportement peut être utilisé pour saisir des mots de passe.
la source
Je voudrais signaler un bug concernant la section Source des données à rechercher dans la première réponse lorsque vous utilisez en dash (-) ou em dash (-) dans le nom de fichier.
Plus précisément, si vous êtes sur le point d'utiliser la première option - les noms de fichiers spécifiés comme arguments , le fichier ne sera pas trouvé. Dès que vous utilisez l'option 2 - stdin via la redirection ou 3 - flux de données à partir d'un tube , findstr trouvera le fichier.
Par exemple, ce simple script batch:
imprimera:
Nom de fichier avec un tiret:
Comme argument
FINDSTR: Impossible d'ouvrir le nom de fichier avec - dash.txt
En tant que stdin via la redirection,
je suis le fichier avec un tiret en.
En tant que flux de données à partir d'un tuyau
je suis le fichier avec un tiret en.
Nom de fichier avec tiret em:
Comme argument
FINDSTR: Impossible d'ouvrir le nom de fichier avec - dash.txt
En tant que stdin via la redirection
je suis le fichier avec un tiret em.
En tant que flux de données à partir d'un tuyau
je suis le fichier avec un tiret em.
J'espère que cela aide.
M.
la source
La
findstr
commande définit leErrorLevel
(ou le code de sortie) sur l'une des valeurs suivantes, étant donné qu'il n'y a pas de commutateurs invalides ou incompatibles et qu'aucune chaîne de recherche ne dépasse la limite de longueur applicable:0
lorsqu'au moins une seule correspondance est rencontrée sur une ligne dans tous les fichiers spécifiés;1
autrement;Une ligne est considérée comme contenant une correspondance lorsque:
/V
option n'est donnée et l'expression de recherche se produit au moins une fois;/V
option est donnée et l'expression de recherche ne se produit pas;Cela signifie que l'
/V
option modifie également la valeur renvoyéeErrorLevel
, mais elle ne le fait pas rétablit seulement!Par exemple, lorsque vous avez un fichier
test.txt
avec deux lignes, dont l'une contient la chaînetext
mais l'autre pas, les deuxfindstr "text" "test.txt"
etfindstr /V "text" "test.txt"
retourne unErrorLevel
de0
.En gros, vous pouvez dire: si
findstr
renvoie au moins une ligne,ErrorLevel
est défini sur0
, sinon sur1
.Notez que l'
/M
option n'affecte pas leErrorLevel
valeur, elle modifie simplement la sortie.(Juste pour être complet: la
find
commande se comporte exactement de la même manière par rapport à l'/V
option etErrorLevel
; l'/C
option n'affecte pasErrorLevel
.)la source
FINDSTR a un bug de couleur que j'ai décrit et résolu à /superuser/1535810/is-there-a-better-way-to-mitigate-this-obscure-color-bug-when-piping-to -findstr / 1538802? noredirect = 1 # comment2339443_1538802
Pour résumer ce thread, le bogue est que si l'entrée est dirigée vers FINDSTR dans un bloc de code entre parenthèses, les codes de couleur d'échappement ANSI en ligne cessent de fonctionner dans les commandes exécutées plus tard. Un exemple de codes de couleur en ligne est:
echo %magenta%Alert: Something bad happened%yellow%
couleur en (où le magenta et le jaune sont des variables définies plus tôt dans le fichier .bat comme codes de couleur d'échappement ANSI correspondants).Ma solution initiale était d'appeler un sous-programme ne rien faire après le FINDSTR. D'une manière ou d'une autre, l'appel ou le retour "réinitialise" tout ce qui doit être réinitialisé.
Plus tard, j'ai découvert une autre solution qui est probablement plus efficace: placez la phrase FINDSTR entre parenthèses, comme dans l'exemple suivant:
echo success | ( FINDSTR /R success )
Placer la phrase FINDSTR dans un bloc de code imbriqué semble isoler le bogue du code de couleur de FINDSTR afin qu'il n'affecte pas ce qui est en dehors de l'imbrication bloquer. Peut-être que cette technique résoudra également d'autres effets secondaires indésirables de FINDSTR .la source
/ D Astuce pour plusieurs répertoires: placez votre liste de répertoires avant la chaîne de recherche. Tout cela fonctionne:
Comme prévu, le chemin est relatif à l'emplacement si vous ne démarrez pas les répertoires avec
\
. Entourer le chemin avec"
est facultatif s'il n'y a pas d'espaces dans les noms de répertoire. La fin\
est facultative. La sortie de l'emplacement inclura le chemin que vous lui donnez. Cela fonctionnera avec ou sans entourer la liste des répertoires avec"
.la source
/D:dirlist Search a semicolon-delimited list of directories
et il est placé avant la chaîne de recherche, donc je ne comprends pas exactement ce que "vous avez trouvé" sur le commutateur / D (et quelles sont les "commandes qui ne fonctionne PAS ") ...findstr
lists / D. Oui, je n'ai aucun argument avec la fonctionnalité documentée, il n'est tout simplement pas documenté sur le fait que l'ordre des attributs compte. Je fais très peu de travail en ligne de commande, donc quand je bricolais une commande, ne sachant pas que l'ordre faisait une différence, j'ajoutais simplement les attributs au fur et à mesure que j'y arrivais (et par ordre alphabétique, C précède D). Je devenais vraiment frustré et j'ai partagé mon expérience "trouvée" pour quiconque ne travaille pas beaucoup avec la ligne de commande.findstr
documentation spécifie que lastrings
partie n'est PAS facultative et que vous devez la placer après les attributs facultatifs et avant la liste de noms de fichiers facultative . Si "votre trouvé" est que l'utilisation d'une commande sans suivre son format d'utilisation provoque une erreur, alors un tel point est bien documenté. Voir la syntaxe de la commande : "La syntaxe apparaît dans l'ordre dans lequel vous devez taper une commande et tous les paramètres qui la suivent"