batch-file - examples - findstr no se puede abrir
¿Cuáles son las características y limitaciones no documentadas del comando FINDSTR de Windows? (6)
/D tip for multiple directories: put your directory list before the search string. These all work:
findstr /D:dir1;dir2 "searchString" *.*
findstr /D:"dir1;dir2" "searchString" *.*
findstr /D:"/path/dir1/;/path/dir2/" "searchString" *.*
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 "
.
El comando FINDSTR de Windows está horriblemente documentado. Hay una línea de comandos muy básica disponible a través de FINDSTR /?
o HELP FINDSTR
, pero lamentablemente es inadecuado. Hay un poquito más de documentación en línea en http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/findstr.mspx?mfr=true .
Hay muchas características y limitaciones de FINDSTR que ni siquiera se insinúan en la documentación. Tampoco podrían anticiparse sin conocimiento previo y / o experimentación cuidadosa.
Entonces la pregunta es: ¿Cuáles son las características y limitaciones de FINDSTR no documentadas?
El propósito de esta pregunta es proporcionar un repositorio de una sola parada de las muchas características no documentadas para que:
A) Los desarrolladores pueden aprovechar al máximo las funciones que están allí.
B) Los desarrolladores no pierden el tiempo preguntándose por qué algo no funciona cuando parece que debería.
Asegúrese de conocer la documentación existente antes de responder. Si la información está cubierta por la AYUDA, entonces no pertenece aquí.
Tampoco es este un lugar para mostrar usos interesantes de FINDSTR. Si una persona lógica puede anticipar el comportamiento de un uso particular de FINDSTR basado en la documentación, entonces no pertenece aquí.
En la misma línea, si una persona lógica puede anticipar el comportamiento de un uso particular basado en la información contenida en cualquier respuesta existente, entonces nuevamente, no pertenece aquí.
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 <DIR> .
2014/04/08 04:28 PM <DIR> ..
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:
- Using
copy
with the/b
option for binary files prevents the addition of the0x1A
character, andfindstr
doesn''t hang on the 3GB file. - Terminating the 3GB file with a different character also causes a
findstr
to hang. - The
0x1A
character doesn''t cause any problems on a "small" file. (Similarly for other terminating characters.) - Adding
CRLF
after0x1A
resolves the problem. (LF
by itself would probably suffice.) - Using
type
to pipe the file intofindstr
works without hanging. (This might be due to a side effect of eithertype
or|
that inserts an additional End Of Line.) - Use redirected input
<
also causesfindstr
to hang. But this is expected; as explained in dbenham''s post : "redirected input must end inLF
" .
Respuesta continuada de la parte 1 anterior - Me encontré con el límite de respuesta de 30,000 caracteres :-(
Soporte de expresiones regulares limitadas (regex)
El soporte FINDSTR para expresiones regulares es extremadamente limitado. Si no está en la documentación de HELP, no es compatible.
Más allá de eso, las expresiones regex que son compatibles se implementan de una manera completamente no estándar, de modo que los resultados pueden ser diferentes de lo que se esperaría de algo como grep o perl.
Regex Line Position anclas ^ y $
^
coincide con el comienzo del flujo de entrada, así como con cualquier posición inmediatamente posterior a <LF>. Dado que FINDSTR también rompe líneas después de <LF>, una expresión regular simple de "^" siempre coincidirá con todas las líneas dentro de un archivo, incluso un archivo binario.
$
coincide con cualquier posición inmediatamente anterior a <CR>. Esto significa que una cadena de búsqueda de expresiones regulares que contiene $
nunca coincidirá con ninguna línea dentro de un archivo de texto de estilo Unix, ni coincidirá con la última línea de un archivo de texto de Windows si falta el marcador EOL de <CR> <LF>.
Nota: Como se comentó anteriormente, la entrada canalizada y redireccionada a FINDSTR puede tener <CR><LF>
adjunto que no está en la fuente. Obviamente, esto puede afectar una búsqueda de expresiones regulares que usa $
.
Cualquier cadena de búsqueda con caracteres antes de ^
o después de $
siempre no podrá encontrar una coincidencia.
Opciones de posición / B / E / X
Las opciones posicionales funcionan igual que ^
y $
, excepto que también funcionan para cadenas de búsqueda literales.
/ B funciona igual que ^
al comienzo de una cadena de búsqueda de expresiones regulares.
/ E funciona igual que $
al final de una cadena de búsqueda de expresiones regulares.
/ X funciona igual que tener ^
al principio y $
al final de una cadena de búsqueda de expresiones regulares.
Límite de palabra Regex
/<
debe ser el primer término en la expresión regular. La expresión regular no coincidirá con nada si otros personajes lo preceden. /<
corresponde al comienzo de la entrada, al comienzo de una línea (la posición inmediatamente posterior a <LF>) o a la posición inmediatamente posterior a cualquier carácter "sin palabra". El siguiente personaje no necesita ser un personaje de "palabra".
/>
debe ser el último término en la expresión regular. La expresión regular no coincidirá con nada si otros personajes lo siguen. />
corresponde al final de la entrada, a la posición inmediatamente anterior a <CR>, o a la posición inmediatamente anterior a cualquier carácter "sin palabra". El personaje precedente no necesita ser un personaje de "palabra".
Aquí hay una lista completa de caracteres "sin palabras", representados como el código de bytes decimales. Nota: esta lista fue compilada en una máquina estadounidense. No sé qué impacto pueden tener otros idiomas en esta lista.
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
Rangos de clase de caracteres Regex [xy]
Los rangos de clases de caracteres no funcionan como se esperaba. Vea esta pregunta: ¿Por qué findstr no maneja el estuche correctamente (en algunas circunstancias)? , junto con esta respuesta: https://.com/a/8767815/1012053 .
El problema es que FINDSTR no clasifica los caracteres por su valor de código de bytes (comúnmente considerado como el código ASCII, pero ASCII solo se define desde 0x00 - 0x7F). La mayoría de las implementaciones de expresiones regulares tratarían [AZ] como todas mayúsculas en mayúsculas en inglés. Pero FINDSTR usa una secuencia de clasificación que corresponde aproximadamente a cómo funciona SORT. Por lo tanto, [AZ] incluye el alfabeto inglés completo, tanto en mayúscula como en minúscula (a excepción de "a"), así como caracteres alfa no ingleses con signos diacríticos.
A continuación se muestra una lista completa de todos los caracteres admitidos por FINDSTR, ordenados en la secuencia de clasificación utilizada por FINDSTR para establecer rangos de clases de caracteres regex. Los caracteres se representan como su valor de código de bytes decimales. Creo que la secuencia de clasificación tiene más sentido si los caracteres se visualizan utilizando la página de códigos 437. Nota: esta lista se compiló en una máquina de EE. UU. No sé qué impacto pueden tener otros idiomas en esta lista.
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
Límite de término de la clase de caracteres Regex y ERROR
FINDSTR no solo está limitado a un máximo de 15 términos de clase de caracteres dentro de una expresión regular, sino que no maneja adecuadamente un intento de superar el límite. El uso de 16 o más términos de clase de caracteres da como resultado un mensaje emergente interactivo de Windows que indica que la herramienta "Find String (QGREP) ha detectado un problema y debe cerrarse. Lamentamos las molestias". El texto del mensaje varía ligeramente según la versión de Windows. Aquí hay un ejemplo de un FINDSTR que fallará:
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]
This bug was reported by DosTips user Judago here . It has been confirmed on XP, Vista, and Windows 7.
Regex searches fail (and may hang indefinitely) if they include byte code 0xFF (decimal 255)
Any regex search that includes byte code 0xFF (decimal 255) will fail. It fails if byte code 0xFF is included directly, or if it is implicitly included within a character class range. 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 <space>
and <tab>
characters. So any character class range that includes both <space>
and <tab>
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 tried 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 <CR>
or <LF>
. There is a bug that allows it to match the End-Of-File if the last line in the file is not terminated by <CR>
or <LF>
. However, the .
will not match an empty file.
For example, a file named "test.txt" containing a single line of x
, without terminating <CR>
or <LF>
, 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.
Prefacio
Gran parte de la información en esta respuesta se ha recopilado en base a experimentos realizados en una máquina Vista. A menos que se indique explícitamente lo contrario, no he confirmado si la información se aplica a otras versiones de Windows.
Salida FINDSTR
La documentación nunca se molesta en explicar el resultado de FINDSTR. Alude al hecho de que las líneas coincidentes están impresas, pero nada más.
El formato de salida de línea coincidente es el siguiente:
nombre de archivo: lineNumber: lineOffset: texto
dónde
fileName: = El nombre del archivo que contiene la línea coincidente. El nombre del archivo no se imprime si la solicitud fue explícitamente para un solo archivo, o si se busca una entrada canalizada o una entrada redirigida. Cuando se imprime, fileName siempre incluirá la información de ruta proporcionada. Se agregará información de ruta adicional si se usa la opción /S
La ruta impresa siempre es relativa a la ruta proporcionada, o relativa al directorio actual si no se proporciona.
Nota: El prefijo de nombre de archivo se puede evitar cuando se buscan archivos múltiples mediante el uso de comodines no estándar (y mal documentados) <
y >
. Las reglas exactas de cómo funcionan estos comodines se pueden encontrar here . Finalmente, puede ver este ejemplo de cómo funcionan los comodines no estándar con FINDSTR .
lineNumber: = El número de línea de la línea correspondiente representada como un valor decimal con 1 que representa la 1ra línea de la entrada. Solo se especifica la opción if /N
impresa.
lineOffset: = El desplazamiento de bytes decimales del inicio de la línea coincidente, donde 0 representa el primer carácter de la 1ra línea. Solo se especifica la opción if /O
impresa. Este no es el desplazamiento del partido dentro de la línea. Es el número de bytes desde el comienzo del archivo hasta el comienzo de la línea.
text = La representación binaria de la línea coincidente, incluidas las <CR> y / o <LF>. No queda nada fuera de la salida binaria, de modo que este ejemplo que coincida con todas las líneas producirá una copia binaria exacta del archivo original.
FINDSTR "^" FILE >FILE_COPY
La mayoría de los caracteres de control y muchos caracteres ASCII extendidos se muestran como puntos en XP
FINDSTR en XP muestra la mayoría de los caracteres de control no imprimibles de líneas coincidentes como puntos (puntos) en la pantalla. Los siguientes caracteres de control son excepciones; se muestran como ellos mismos: Pestaña 0x09, LineFeed 0x0A, Pestaña Vertical 0x0B, Alimentación de formulario 0x0C, Retorno de carro 0x0D.
XP FINDSTR también convierte una cantidad de caracteres ASCII extendidos a puntos también. Los caracteres ASCII extendidos que se muestran como puntos en XP son los mismos que se transforman cuando se suministran en la línea de comando. Consulte la sección "Límites de caracteres para parámetros de línea de comandos - Transformación ASCII ampliada" , más adelante en esta publicación.
Los caracteres de control y ASCII extendido no se convierten en puntos en XP si la salida se canaliza, se redirige a un archivo o dentro de una cláusula FOR IN ().
Vista y Windows 7 siempre muestran todos los caracteres como ellos mismos, nunca como puntos.
Códigos de retorno (ERRORLEVEL)
- 0 (éxito)
- Match se encontró en al menos una línea de al menos un archivo.
- 1 (error)
- No se encontraron coincidencias en ninguna línea de ningún archivo.
- Color no válido especificado por la opción
/A:xx
- 2 (error)
- Opciones incompatibles
/L
y/R
ambos especificados - Falta el argumento después de
/A:
/F:
/C:
/D:
o/G:
- Archivo especificado por
/F:file
o/G:file
no encontrado
- Opciones incompatibles
- 255 (error)
- Demasiados términos de clase de carácter de expresión regular
ver límite de términos de la clase de caracteres Regex y ERROR en la parte 2 de la respuesta
- Demasiados términos de clase de carácter de expresión regular
Fuente de datos para buscar (Actualización basada en pruebas con Windows 7)
Findstr puede buscar datos solo desde una de las siguientes fuentes:
nombres de archivos especificados como argumentos y / o utilizando la opción
/F:file
.stdin a través de la redirección
findstr "searchString" <file
secuencia de datos de un
type file | findstr "searchString"
tuberíatype file | findstr "searchString"
type file | findstr "searchString"
Los argumentos / opciones tienen prioridad sobre la redirección, que tiene prioridad sobre los datos canalizados.
Argumentos del nombre de archivo y /F:file
puede combinarse. Se pueden usar múltiples argumentos de nombre de archivo. Si se especifican múltiples /F:file
opciones de /F:file
, solo se utiliza la última. Las comodines están permitidas en los argumentos de nombre de archivo, pero no dentro del archivo al que apunta /F:file
.
Fuente de cadenas de búsqueda (Actualizado según las pruebas con Windows 7)
Las opciones /G:file
y /C:string
se pueden combinar. Se pueden especificar múltiples /C:string
opciones de /C:string
. Si se especifican múltiples /G:file
opciones de /G:file
, solo se utiliza la última. Si se usa /G:file
o /C:string
, se supone que todos los argumentos que no son de opción son archivos para buscar. Si no se usa ni /G:file
ni /C:string
, entonces el primer argumento no opcional se trata como una lista delimitada por espacios de términos de búsqueda.
Los nombres de archivo no se deben citar dentro del archivo cuando se usa la opción /F:FILE
.
Los nombres de archivo pueden contener espacios y otros caracteres especiales. La mayoría de los comandos requieren que dichos nombres de archivo sean citados. Pero la opción FINDSTR /F:files.txt
requiere que los nombres de archivos dentro de files.txt NO se puedan citar. El archivo no se encontrará si el nombre es citado.
ERROR - Los nombres de archivo cortos 8.3 pueden romper las opciones /D
y /S
Al igual que con todos los comandos de Windows, FINDSTR intentará hacer coincidir el nombre largo y el nombre corto 8.3 al buscar archivos para buscar. Suponga que la carpeta actual contiene los siguientes archivos no vacíos:
b1.txt
b.txt2
c.txt
El siguiente comando encontrará con éxito los 3 archivos:
findstr /m "^" *.txt
b.txt2
coincide porque el nombre corto correspondiente B9F64~1.TXT
coincide. Esto es consistente con el comportamiento de todos los demás comandos de Windows.
Pero un error con las opciones /D
y /S
hace que los siguientes comandos solo encuentren b1.txt
findstr /m /d:. "^" *.txt
findstr /m /s "^" *.txt
El error evita que se encuentre b.txt2
, así como todos los nombres de archivo que se ordenan después de b.txt2
dentro del mismo directorio. Se encuentran archivos adicionales que se ordenan antes, como a.txt
. Los archivos adicionales que se ordenan más tarde, como d.txt
, se pierden una vez que se ha activado el error.
Cada directorio buscado se trata de manera independiente. Por ejemplo, la opción /S
comenzaría a buscar correctamente en una carpeta secundaria después de no poder encontrar los archivos en el elemento primario, pero una vez que el error provoque que se pierda un nombre de archivo corto en el elemento secundario, todos los archivos subsiguientes en esa carpeta secundaria también ser extrañado
Los comandos funcionan sin errores si se crean los mismos nombres de archivos en una máquina que tiene la generación de nombres NTFS 8.3 deshabilitada. Por supuesto, b.txt2
no se encontraría, pero c.txt
se encontraría correctamente.
No todos los nombres cortos activan el error. Todas las instancias de comportamiento con errores que he visto implican una extensión de más de 3 caracteres con un nombre corto de 8.3 que comienza igual que un nombre normal que no requiere un nombre 8.3.
El error ha sido confirmado en XP, Vista y Windows 7.
Caracteres no imprimibles y la opción /P
La opción /P
hace que FINDSTR omita cualquier archivo que contenga cualquiera de los siguientes códigos de bytes decimales:
0-7, 14-25, 27-31.
Dicho de otra manera, la opción /P
solo omitirá archivos que contengan caracteres de control no imprimibles. Los caracteres de control son códigos menores o iguales a 31 (0x1F). FINDSTR trata los siguientes caracteres de control como imprimibles:
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)
Todos los demás caracteres de control se tratan como no imprimibles, cuya presencia hace que la opción /P
omita el archivo.
La entrada canalizada y redirigida puede tener <CR><LF>
adjuntado
Si la entrada está conectada y el último carácter de la transmisión no es <LF>
, entonces FINDSTR agregará automáticamente <CR><LF>
a la entrada. Esto se ha confirmado en XP, Vista y Windows 7. (Solía pensar que Windows Pipe fue responsable de modificar la entrada, pero desde entonces descubrí que FINDSTR está haciendo la modificación).
Lo mismo es cierto para la entrada redirigida en Vista. Si el último carácter de un archivo utilizado como entrada redirigida no es <LF>
, entonces FINDSTR agregará automáticamente <CR><LF>
a la entrada. Sin embargo, XP y Windows 7 no alteran la entrada redirigida.
FINDSTR se bloquea en XP y Windows 7 si la entrada redirigida no finaliza con <LF>
Esta es una desagradable "característica" en XP y Windows 7. Si el último carácter de un archivo utilizado como entrada redirigida no termina con <LF>
, entonces FINDSTR se bloqueará indefinidamente una vez que llegue al final del archivo redirigido.
La última línea de datos de Piped se puede ignorar si consta de un solo carácter
Si la entrada está canalizada y la última línea consiste en un solo carácter que no está seguido por <LF>
, entonces FINDSTR ignora por completo la última línea.
Ejemplo: el primer comando con un solo carácter y sin <LF>
no coincide, pero el segundo comando con 2 caracteres funciona bien, al igual que el tercer comando que tiene un carácter con terminación de línea nueva.
> set /p "=x" <nul | findstr "^"
> set /p "=xx" <nul | findstr "^"
xx
> echo x| findstr "^"
x
Reportado por el usuario de DosTips, Sponge Belly, en el nuevo error de findstr . Confirmado en XP, Windows 7 y Windows 8. Aún no he oído hablar de Vista. (Ya no tengo Vista para probar).
Sintaxis de opciones
Las opciones pueden tener el prefijo /
o -
opciones se pueden concatenar después de un único /
o -
. Sin embargo, la lista de opciones concatenadas puede contener, como máximo, una opción de múltiples caracteres como OFF o F :, y la opción de caracteres múltiples debe ser la última opción de la lista.
Las siguientes son formas equivalentes de expresar una búsqueda de expresiones regulares insensible a mayúsculas y minúsculas para cualquier línea que contenga tanto "hola" como "adiós" en cualquier orden
/i /r /c:"hello.*goodbye" /c:"goodbye.*hello"
-i -r -c:"hello.*goodbye" /c:"goodbye.*hello"
/irc:"hello.*goodbye" /c:"goodbye.*hello"
Límites de longitud de cadena de búsqueda
En Vista, la longitud máxima permitida para una sola cadena de búsqueda es de 511 bytes. Si alguna cadena de búsqueda excede 511, el resultado es FINDSTR: Search string too long.
error con ERRORLEVEL 2.
Al realizar una búsqueda de expresión regular, la longitud máxima de la cadena de búsqueda es 254. Una expresión regular con una longitud entre 255 y 511 dará como resultado un FINDSTR: Out of memory
error de falta FINDSTR: Out of memory
con ERRORLEVEL 2. Una longitud de expresión regular> 511 da como resultado FINDSTR: Search string too long.
error.
En Windows XP, la longitud de la cadena de búsqueda es aparentemente más corta. Error de Findstr: "Cadena de búsqueda demasiado larga": ¿cómo extraer y hacer coincidir subcadena en el bucle "for"? El límite de XP es de 127 bytes para búsquedas literales y de expresiones regulares.
Límites de longitud de línea
Los archivos especificados como un argumento de línea de comando o mediante la opción / F: FILE no tienen límite de longitud de línea conocido. Las búsquedas se ejecutaron correctamente en un archivo de 128 MB que no contenía un solo <LF>.
Los datos canalizados y la entrada redirigida están limitados a 8191 bytes por línea. Este límite es una "característica" de FINDSTR. No es inherente a las tuberías ni a la redirección. FINDSTR utilizando stdin redirigido o entrada canalizada nunca coincidirá con ninguna línea que sea> = 8k bytes. Las líneas> = 8k generan un mensaje de error a stderr, pero ERRORLEVEL sigue siendo 0 si la cadena de búsqueda se encuentra en al menos una línea de al menos un archivo.
Tipo predeterminado de búsqueda: expresión literal frente a expresión regular
/C:"string"
- El valor predeterminado es / L literal. Combinar explícitamente la opción / L con / C: "cadena" ciertamente funciona pero es redundante.
"string argument"
: el valor predeterminado depende del contenido de la primera cadena de búsqueda. (Recuerde que <espacio> se usa para delimitar cadenas de búsqueda.) Si la primera cadena de búsqueda es una expresión regular válida que contiene al menos un metacaracido sin escape, todas las cadenas de búsqueda se tratan como expresiones regulares. De lo contrario, todas las cadenas de búsqueda se tratan como literales. Por ejemplo, "51.4 200"
se tratará como dos expresiones regulares porque la primera cadena contiene un punto no escapado, mientras que "200 51.4"
se tratarán como dos literales porque la primera cadena no contiene ningún metacaraculo.
/G:file
: el valor predeterminado depende del contenido de la primera línea no vacía del archivo. Si la primera cadena de búsqueda es una expresión regular válida que contiene al menos un metacarácter sin escape, todas las cadenas de búsqueda se tratan como expresiones regulares. De lo contrario, todas las cadenas de búsqueda se tratan como literales.
Recomendación: especifique siempre explícitamente /L
opción literal o /R
opción de expresión regular cuando utilice "string argument"
o /G:file
.
ERROR: especificar varias cadenas de búsqueda literales puede dar resultados poco confiables
El siguiente ejemplo FINDSTR simple no puede encontrar una coincidencia, aunque debería.
echo ffffaaa|findstr /l "ffffaaa faffaffddd"
Este error ha sido confirmado en Windows Server 2003, Windows XP, Vista y Windows 7.
Según los experimentos, FINDSTR puede fallar si se cumplen todas las condiciones siguientes:
- La búsqueda usa múltiples cadenas de búsqueda literales
- Las cadenas de búsqueda son de diferentes longitudes
- Una cadena de búsqueda corta tiene cierta cantidad de superposición con una cadena de búsqueda más larga
- La búsqueda es sensible a mayúsculas y minúsculas (opción no
/I
)
En cada falla que he visto, siempre falla una de las cadenas de búsqueda más cortas.
Para obtener más información, consulte ¿Por qué este ejemplo FINDSTR con múltiples cadenas de búsqueda literales no encuentra una coincidencia?
Citas y backslahses dentro de los argumentos de línea de comando - Nota:
La información dentro de esta sección resaltada no es 100% precisa. Después de escribir esta sección, el usuario MC ND me señaló una referencia que documenta cómo la biblioteca Microsoft C / C ++ analiza los parámetros . Es terriblemente complicado, pero parece predecir con precisión las reglas de barra invertida y de cotización para los argumentos de la línea de comando FINDSTR. Le recomiendo que use la información resaltada a continuación como una guía, pero si desea información más precisa, consulte el enlace.Cita de escape dentro de cadenas de búsqueda de línea de comando
Las comillas dentro de las cadenas de búsqueda de la línea de comando deben ser escapadas con una barra invertida como/"
. Esto es cierto tanto para cadenas de búsqueda literales como de expresión regular. Esta información ha sido confirmada en XP, Vista y Windows 7.Nota: La cita también puede necesitar ser escapada para el analizador CMD.EXE, pero esto no tiene nada que ver con FINDSTR. Por ejemplo, para buscar una cita simple, puede usar:
FINDSTR /^" file && echo found || echo not found
Escapar de la barra invertida dentro de las líneas de búsqueda literal de la línea de comando
La barra diagonal inversa en una cadena de búsqueda literal normalmente se puede representar como/
o como//
. Por lo general son equivalentes. (Puede haber casos inusuales en Vista donde la barra diagonal inversa siempre se debe escapar, pero ya no tengo una máquina Vista para probar) .Pero hay algunos casos especiales:
Cuando se buscan barras inversas consecutivas, se debe escapar a todas menos a la última. La última barra invertida puede ser escapada opcionalmente.
//
se puede codificar como///
o////
///
se puede codificar como/////
o//////
La búsqueda de una o más barras invertidas antes de una cita es extraña. La lógica sugeriría que la cita debe ser escapada, y cada una de las barras invertidas debe escaparse, ¡pero esto no funciona! En cambio, cada una de las barras diagonales iniciales debe tener doble escape, y la cita se escapa normalmente:
/"
debe estar codificado como/////"
//"
debe estar codificado como/////////"
Como se indicó anteriormente, una o más citas escapadas también pueden requerir escaparse con
^
para el analizador CMDLa información en esta sección ha sido confirmada en XP y Windows 7.
Escapar de la barra invertida dentro de las líneas de búsqueda de expresiones regex de la línea de comando
Vista solamente: la barra diagonal inversa en una expresión regular debe tener doble escape como
////
, o bien solo escapó dentro de una clase de caracteres establecida como[//]
XP y Windows 7: la barra diagonal inversa en una expresión regular siempre se puede representar como
[//]
. Normalmente se puede representar como//
. Pero esto nunca funciona si la barra invertida precede a una comilla escapada.Una o más barras diagonales inversas antes de una cita escapada se deben escapar por partida doble o codificarse como
[//]
/"
puede estar codificado como/////"
o[//]/"
//"
puede estar codificado como/////////"
o[//][//]/"
o//[//]/"
Escaping Quote and Backslash dentro de / G: cadenas de búsqueda FILE literal
Las comillas independientes y las barras diagonales inversas dentro de un archivo de cadena de búsqueda literal especificado por / G: archivo no necesitan ser escapadas, pero pueden serlo.
"
y /"
son equivalentes.
/
y //
son equivalentes.
Si la intención es encontrar //, entonces al menos la barra diagonal inversa inicial debe ser escapada. Ambos ///
y ////
funcionan.
Si la intención es encontrar / ", entonces se debe escapar al menos la barra diagonal inversa. Tanto //"
como ///"
funcionan.
Escaping Quote and Backslash dentro de / G: FILE cadenas de búsqueda de expresiones regex
Este es el único caso en el que las secuencias de escape funcionan según lo esperado según la documentación. Quote no es un metacaracter regex, por lo que no necesita ser escapado (pero puede ser). La barra invertida es un metacaracter regex, por lo que debe escaparse.
Límites de caracteres para parámetros de línea de comando - Transformación ASCII extendida
El carácter nulo (0x00) no puede aparecer en ninguna cadena en la línea de comando. Cualquier otro carácter de un solo byte puede aparecer en la cadena (0x01 - 0xFF). Sin embargo, FINDSTR convierte muchos caracteres ASCII extendidos que encuentra dentro de los parámetros de la línea de comandos en otros caracteres. Esto tiene un gran impacto de dos maneras:
1) Muchos caracteres ASCII extendidos no coincidirán si se usan como una cadena de búsqueda en la línea de comando. Esta limitación es la misma para búsquedas literales y de expresiones regulares. Si una cadena de búsqueda debe contener ASCII extendido, entonces se debe usar la opción /G:FILE
su lugar.
2) FINDSTR puede no encontrar un archivo si el nombre contiene caracteres ASCII extendidos y el nombre del archivo se especifica en la línea de comando. Si un archivo que se va a buscar contiene ASCII extendido en el nombre, se debe usar la opción /F:FILE
.
Aquí hay una lista completa de las transformaciones de caracteres ASCII extendidas que FINDSTR realiza en cadenas de línea de comandos. Cada carácter se representa como el valor del código decimal de bytes. El primer código representa el carácter tal como se proporciona en la línea de comando, y el segundo código representa el personaje en el que se transforma. Nota: esta lista fue compilada en una máquina estadounidense. No sé qué impacto pueden tener otros idiomas en esta lista.
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
Cualquier carácter> 0 que no se encuentre en la lista anterior se trata como sí mismo, incluidos <CR>
y < LF>
. La forma más fácil de incluir caracteres impares como <CR>
y <LF>
es introducirlos en una variable de entorno y usar la expansión retrasada dentro del argumento de línea de comando.
Límites de caracteres para cadenas encontradas en archivos especificados por / G: ARCHIVO y / F: opciones de ARCHIVO
El carácter nul (0x00) puede aparecer en el archivo, pero funciona como el terminador de cadena C. Cualquier carácter después de un carácter nul se trata como una cadena diferente como si estuvieran en otra línea.
Los caracteres <CR>
y <LF>
se tratan como terminadores de línea que terminan una cadena y no se incluyen en la cadena.
Todos los demás caracteres de un solo byte se incluyen perfectamente dentro de una cadena.
Buscando archivos Unicode
FINDSTR no puede buscar correctamente la mayoría de Unicode (UTF-16, UTF-16LE, UTF-16BE, UTF-32) porque no puede buscar nulos bytes y Unicode normalmente contiene muchos bytes nulos.
Sin embargo, el comando TYPE convierte UTF-16LE con BOM en un conjunto de caracteres de un solo byte, por lo que un comando como el siguiente funcionará con UTF-16LE con BOM.
type unicode.txt|findstr "search"
Tenga en cuenta que los puntos de código Unicode que no son compatibles con su página de códigos activa se convertirán a ?
caracteres.
Es posible buscar UTF-8 siempre que su cadena de búsqueda contenga solo ASCII. Sin embargo, la salida de la consola de cualquier carácter UTF-8 de múltiples bytes no será correcta. Pero si redirige la salida a un archivo, el resultado se codificará correctamente UTF-8. Tenga en cuenta que si el archivo UTF-8 contiene una lista de materiales, entonces la lista de materiales se considerará como parte de la primera línea, lo que podría arrojar una búsqueda que coincida con el comienzo de una línea.
Es posible buscar caracteres UTF-8 de múltiples bytes si coloca la cadena de búsqueda en un archivo de búsqueda codificado UTF-8 (sin lista de materiales) y utiliza la opción / G.
Fin de la línea
FINDSTR rompe líneas inmediatamente después de cada <LF>. La presencia o ausencia de <CR> no tiene ningún impacto en los saltos de línea.
Búsqueda a través de saltos de línea
Como se esperaba, el .
El metacaracter regex no coincidirá con <CR> o <LF>. Pero es posible buscar a través de un salto de línea usando una cadena de búsqueda de línea de comando. Los caracteres <CR> y <LF> deben coincidir explícitamente. Si se encuentra una coincidencia de varias líneas, solo se imprime la primera línea del partido. FINDSTR luego vuelve a la segunda línea en la fuente y comienza la búsqueda una vez más, una especie de función de tipo "mirar hacia adelante".
Suponer que TEXT.TXT tiene estos contenidos (podría ser de estilo Unix o Windows)
A
A
A
B
A
A
Entonces este 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
da estos resultados
1:A
2:A
5:A
La búsqueda entre saltos de línea con la opción / G: FILE es imprecisa porque la única forma de hacer coincidir <CR> o <LF> es a través de una expresión de rango de clase de caracteres regex que empareda los caracteres EOL.
[<TAB>-<0x0B>]
coincide con <LF>, pero también coincide con <TAB> y <0x0B>[<0x0C>-!]
Coincide con <CR>, pero también coincide con <0x0C> y!Nota: las anteriores son representaciones simbólicas del flujo de bytes regex ya que no puedo representar gráficamente los caracteres.
La respuesta continuó en la parte 2 a continuación ...
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
will print:
Filename with en dash:
As argument
FINDSTR: Cannot open filename with - dash.txtAs 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.txtAs stdin via redirection
I am the file with an em dash.As datastream from a pipe
I am the file with an em dash.
Espero eso ayude.
M.
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
Este código:
find "search string" < input.txt > matchedLines.txt
find /V "search string" < input.txt > unmatchedLines.txt
... produce the same result than this one:
< input.txt (
find "search string" > matchedLines.txt
find /V "search string" > 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 .