O comando FINDSTR do Windows está terrivelmente documentado. Existe uma ajuda muito básica da linha de comando disponível em FINDSTR /?
, ou HELP FINDSTR
, mas é lamentavelmente inadequada. Há um pouco mais de documentação online em https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr .
Existem muitos recursos e limitações do FINDSTR que nem são mencionados na documentação. Nem poderiam ser antecipados sem conhecimento prévio e / ou experimentação cuidadosa.
Portanto, a pergunta é: quais são os recursos e limitações não documentadas do FINDSTR?
O objetivo desta pergunta é fornecer um repositório único dos muitos recursos não documentados para que:
A) Os desenvolvedores podem aproveitar ao máximo os recursos existentes.
B) Os desenvolvedores não perdem tempo se perguntando por que algo não funciona quando parece que deveria.
Certifique-se de conhecer a documentação existente antes de responder. Se as informações são cobertas pela AJUDA, elas não pertencem aqui.
Este também não é um lugar para mostrar usos interessantes do FINDSTR. Se uma pessoa lógica puder antecipar o comportamento de um uso específico do FINDSTR com base na documentação, ele não pertence aqui.
Na mesma linha, se uma pessoa lógica poderia antecipar o comportamento de um uso específico com base nas informações contidas em qualquer resposta existente, então, novamente, ele não pertence aqui.
fonte
grep
que é muito bem entendido e documentado :-) Veja stackoverflow.com/questions/2635740/… por exemplo.Respostas:
Prefácio
Muitas das informações nesta resposta foram coletadas com base em experimentos executados em uma máquina Vista. Salvo indicação explícita em contrário, não confirmei se as informações se aplicam a outras versões do Windows.
Saída FINDSTR
A documentação nunca se preocupa em explicar a saída do FINDSTR. Alude ao fato de que linhas correspondentes são impressas, mas nada mais.
O formato da saída de linha correspondente é o seguinte:
filename: lineNumber: lineOffset: text
Onde
fileName: = O nome do arquivo que contém a linha correspondente. O nome do arquivo não será impresso se a solicitação for explicitamente para um único arquivo ou se estiver pesquisando entrada canalizada ou redirecionada. Quando impresso, o nome do arquivo sempre inclui todas as informações de caminho fornecidas. Informações adicionais sobre o caminho serão adicionadas se a
/S
opção for usada. O caminho impresso é sempre relativo ao caminho fornecido ou ao diretório atual, se nenhum for fornecido.Nota - O prefixo do nome do arquivo pode ser evitado ao pesquisar vários arquivos usando os curingas não padrão (e mal documentados)
<
e>
. As regras exatas de como esses curingas funcionam podem ser encontradas aqui . Por fim, você pode ver este exemplo de como os curingas não padrão funcionam com o FINDSTR .lineNumber: = O número da linha da linha correspondente representada como um valor decimal com 1 representando a 1ª linha da entrada. Impresso apenas se a
/N
opção for especificada.lineOffset: = O deslocamento de bytes decimais do início da linha correspondente, com 0 representando o 1º caractere da 1ª linha. Impresso apenas se a
/O
opção for especificada. Este não éo deslocamento da partida dentro da linha. É o número de bytes desde o início do arquivo até o início da linha.text = A representação binária da linha correspondente, incluindo qualquer <CR> e / ou <LF>. Nada é deixado de fora da saída binária, de modo que este exemplo que corresponda a todas as linhas produza uma cópia binária exata do arquivo original.
A opção / A define a cor do fileName :, lineNumber: e lineOffset: somente saída. O texto da linha correspondente é sempre impresso com a cor atual do console. A opção / A somente tem efeito quando a saída é exibida diretamente no console. A opção / A não terá efeito se a saída for redirecionada para um arquivo ou canalizada. Veja a edição 2018-08-18 na resposta de Aacini para obter uma descrição do comportamento do buggy quando a saída é redirecionada para CON.
A maioria dos caracteres de controle e muitos caracteres ASCII estendidos são exibidos como pontos no XP O
FINDSTR no XP exibe a maioria dos caracteres de controle não imprimíveis das linhas correspondentes como pontos (pontos) na tela. Os seguintes caracteres de controle são exceções; eles são exibidos como eles mesmos: Guia 0x09, Alimentação de linha 0x0A, Guia vertical 0x0B, Alimentação de formulário 0x0C, Retorno de carro 0x0D.
O XP FINDSTR também converte vários caracteres ASCII estendidos em pontos também. Os caracteres ASCII estendidos que são exibidos como pontos no XP são os mesmos que são transformados quando fornecidos na linha de comando. Consulte a seção "Limites de caracteres para parâmetros de linha de comando - transformação ASCII estendida" , posteriormente nesta postagem
Caracteres de controle e ASCII estendido não serão convertidos em pontos no XP se a saída for canalizada, redirecionada para um arquivo ou dentro de uma cláusula FOR IN ().
O Vista e o Windows 7 sempre exibem todos os caracteres como eles mesmos, nunca como pontos.
Códigos de retorno (ERRORLEVEL)
/A:xx
opção/L
e/R
ambas especificadas/A:
,/F:
,/C:
,/D:
, ou/G:
/F:file
ou/G:file
não encontradoconsulte Limite de termos de classe de caracteres Regex e BUG na parte 2 da resposta
Origem dos dados a serem pesquisados (atualizado com base nos testes com o Windows 7) O
Findstr pode pesquisar dados de apenas uma das seguintes fontes:
nomes de arquivos especificados como argumentos e / ou usando a
/F:file
opçãostdin via redirecionamento
findstr "searchString" <file
fluxo de dados de um tubo
type file | findstr "searchString"
Argumentos / opções têm precedência sobre o redirecionamento, que tem precedência sobre dados canalizados.
Argumentos de nome de arquivo e
/F:file
podem ser combinados. Vários argumentos de nome de arquivo podem ser usados. Se várias/F:file
opções forem especificadas, somente a última será usada. Curingas são permitidos nos argumentos do nome do arquivo, mas não no arquivo apontado por/F:file
.Origem das strings de pesquisa (atualizadas com base em testes com o Windows 7)
As opções
/G:file
e/C:string
podem ser combinadas. Várias/C:string
opções podem ser especificadas. Se várias/G:file
opções forem especificadas, somente a última será usada. Se um/G:file
ou/C:string
for usado, todos os argumentos que não sejam de opção serão considerados arquivos a serem pesquisados. Se nem/G:file
nem/C:string
for usado, o primeiro argumento não opcional será tratado como uma lista delimitada por espaço de termos de pesquisa.Os nomes de arquivos não devem ser citados no arquivo ao usar a
/F:FILE
opçãoOs nomes de arquivos podem conter espaços e outros caracteres especiais. A maioria dos comandos exige que esses nomes de arquivos sejam citados. Mas a
/F:files.txt
opção FINDSTR exige que os nomes de arquivos em files.txt NÃO sejam citados. O arquivo não será encontrado se o nome estiver entre aspas.BUG - Short nomes de arquivo 8.3 pode quebrar o
/D
e/S
opçõesTal como acontece com todos os comandos do Windows, FINDSTR tentará coincidir com o nome longo e curto 8.3 nome quando se olha para os arquivos a serem pesquisados. Suponha que a pasta atual contenha os seguintes arquivos não vazios:
O comando a seguir encontrará com êxito todos os 3 arquivos:
b.txt2
corresponde porque o nome abreviado correspondenteB9F64~1.TXT
corresponde. Isso é consistente com o comportamento de todos os outros comandos do Windows.Mas um erro com as opções
/D
e/S
faz com que os seguintes comandos encontrem apenasb1.txt
O erro evita que
b.txt2
seja encontrado, assim como todos os nomes de arquivos que são classificadosb.txt2
no mesmo diretório. Arquivos adicionais que são classificados antes, comoa.txt
, são encontrados. Arquivos adicionais que são classificados mais tarde, comod.txt
, são perdidos quando o bug foi acionado.Cada diretório pesquisado é tratado de forma independente. Por exemplo, a
/S
opção começaria a pesquisar com êxito em uma pasta filha após não encontrar os arquivos no pai, mas assim que o bug fizer com que um nome de arquivo curto seja perdido no filho, todos os arquivos subsequentes nessa pasta filho também serão perdidos .Os comandos funcionam sem erros se os mesmos nomes de arquivo forem criados em uma máquina com a geração de nomes NTFS 8.3 desativada. Claro
b.txt2
que não seria encontrado, masc.txt
seria encontrado corretamente.Nem todos os nomes abreviados acionam o bug. Todas as instâncias de comportamento que vi envolvem uma extensão com mais de 3 caracteres com um nome 8.3 curto que começa da mesma forma que um nome normal que não requer um nome 8.3.
O bug foi confirmado no XP, Vista e Windows 7.
Caracteres não imprimíveis e a
/P
opçãoA
/P
opção faz com que o FINDSTR ignore qualquer arquivo que contenha qualquer um dos seguintes códigos de bytes decimais:0-7, 14-25, 27-31.
Em outras palavras, a
/P
opção ignorará apenas arquivos que contenham caracteres de controle não imprimíveis. Os caracteres de controle são códigos menores ou iguais a 31 (0x1F). O FINDSTR trata os seguintes caracteres de controle como imprimíveis:Todos os outros caracteres de controle são tratados como não imprimíveis, cuja presença faz com que a
/P
opção ignore o arquivo.A entrada canalizada e redirecionada pode ter sido
<CR><LF>
anexadaSe a entrada for canalizada e o último caractere do fluxo não for
<LF>
, o FINDSTR será automaticamente anexado<CR><LF>
à entrada. Isso foi confirmado no XP, Vista e Windows 7. (Eu costumava pensar que o canal do Windows era responsável por modificar a entrada, mas descobri que o FINDSTR está realmente fazendo a modificação).O mesmo vale para a entrada redirecionada no Vista. Se o último caractere de um arquivo usado como entrada redirecionada não for
<LF>
, o FINDSTR será anexado automaticamente<CR><LF>
à entrada. No entanto, XP e Windows 7 não alteram a entrada redirecionada.O FINDSTR trava no XP e no Windows 7 se a entrada redirecionada não terminar com
<LF>
Esse é um "recurso" desagradável no XP e no Windows 7. Se o último caractere de um arquivo usado como entrada redirecionada não terminar
<LF>
, o FINDSTR travará indefinidamente assim que atinge o final do arquivo redirecionado.A última linha de dados canalizados pode ser ignorada se consistir em um único caractere.
Se a entrada é canalizada e a última linha consiste em um único caractere que não é seguido por
<LF>
, o FINDSTR ignora completamente a última linha.Exemplo - O primeiro comando com um único caractere e sem
<LF>
falha na correspondência, mas o segundo comando com 2 caracteres funciona bem, assim como o terceiro comando que possui um caractere com o término da nova linha.Relatado pelo usuário do DosTips Sponge Belly no novo bug do findstr . Confirmado no XP, Windows 7 e Windows 8. Ainda não ouviu falar do Vista. (Eu não tenho mais o Vista para testar).
Sintaxe da opção As
opções podem ser prefixadas com
/
ou-
Opções podem ser concatenadas após um único/
ou-
. No entanto, a lista de opções concatenadas pode conter no máximo uma opção de vários caracteres, como OFF ou F:, e a opção de vários caracteres deve ser a última opção da lista.A seguir, são apresentadas todas as formas equivalentes de expressar uma regex sem distinção entre maiúsculas e minúsculas, procurando por qualquer linha que contenha "olá" e "adeus" em qualquer ordem
/i /r /c:"hello.*goodbye" /c:"goodbye.*hello"
-i -r -c:"hello.*goodbye" /c:"goodbye.*hello"
/irc:"hello.*goodbye" /c:"goodbye.*hello"
Limites de comprimento da string de pesquisa
No Vista, o comprimento máximo permitido para uma única string de pesquisa é de 511 bytes. Se qualquer sequência de pesquisa exceder 511, o resultado será um
FINDSTR: Search string too long.
erro no ERRORLEVEL 2.Ao fazer uma pesquisa de expressão regular, o comprimento máximo da string de pesquisa é 254. Uma expressão regular com comprimento entre 255 e 511 resultará em um
FINDSTR: Out of memory
erro com ERRORLEVEL 2. Um comprimento de expressão regular> 511 resulta noFINDSTR: Search string too long.
erro.No Windows XP, o comprimento da string de pesquisa é aparentemente menor. Erro Findstr: "A cadeia de pesquisa é muito longa": como extrair e corresponder a substring no loop "for"? O limite do XP é de 127 bytes para pesquisas literais e regex.
Limites de comprimento de linha Os
arquivos especificados como argumento de linha de comando ou através da opção / F: FILE não possuem limite de comprimento de linha conhecido. As pesquisas foram executadas com êxito em um arquivo de 128 MB que não continha um único <LF>.
Dados canalizados e entrada redirecionada são limitados a 8191 bytes por linha. Esse limite é um "recurso" do FINDSTR. Não é inerente a pipes ou redirecionamentos. O FINDSTR usando stdin redirecionado ou entrada canalizada nunca corresponderá a nenhuma linha que seja> = 8k bytes. Linhas> = 8k geram uma mensagem de erro para stderr, mas ERRORLEVEL ainda é 0 se a cadeia de pesquisa for encontrada em pelo menos uma linha de pelo menos um arquivo.
Tipo de pesquisa padrão: Literal vs Expressão regular
/C:"string"
- O padrão é / L literal. Combinar explicitamente a opção / L com / C: "string" certamente funciona, mas é redundante."string argument"
- O padrão depende do conteúdo da primeira cadeia de pesquisa. (Lembre-se de que <espaço> é usado para delimitar cadeias de caracteres de pesquisa.) Se a primeira cadeia de caracteres de pesquisa for uma expressão regular válida que contenha pelo menos um meta-caractere não escapado, todas as cadeias de caracteres de pesquisa serão tratadas como expressões regulares. Caso contrário, todas as cadeias de pesquisa serão tratadas como literais. Por exemplo,"51.4 200"
será tratado como duas expressões regulares porque a primeira string contém um ponto não escapado, enquanto"200 51.4"
será tratado como dois literais porque a primeira string não contém meta-caracteres./G:file
- O padrão depende do conteúdo da primeira linha não vazia no arquivo. Se a primeira cadeia de pesquisa for uma expressão regular válida que contenha pelo menos um meta-caractere não escapado, todas as cadeias de pesquisa serão tratadas como expressões regulares. Caso contrário, todas as cadeias de pesquisa serão tratadas como literais.Recomendação - Sempre especifique explicitamente
/L
a opção literal ou/R
a expressão regular ao usar"string argument"
ou/G:file
.Erro - especificar várias seqüências de pesquisa literais pode gerar resultados não confiáveis
O exemplo simples a seguir de FINDSTR falha ao encontrar uma correspondência, mesmo que deva.
Este bug foi confirmado no Windows Server 2003, Windows XP, Vista e Windows 7.
Com base em experimentos, o FINDSTR pode falhar se todas as seguintes condições forem atendidas:
/I
opção)Em todas as falhas que eu vi, é sempre uma das seqüências de pesquisa mais curtas que falha.
Para obter mais informações, consulte Por que esse exemplo do FINDSTR com várias seqüências de pesquisa literais não encontra uma correspondência?
Escapando
aspas e barra invertida em cadeias de pesquisa literais / G: FILE As aspas e barras invertidas independentes em um arquivo de cadeia de pesquisa literal especificado por / G: file não precisam ser escapadas, mas podem ser.
"
e\"
são equivalentes.\
e\\
são equivalentes.Se a intenção é encontrar \\, pelo menos a barra invertida principal deve ser escapada. Ambos
\\\
e\\\\
trabalho.Se a intenção é encontrar \ ", pelo menos a barra invertida principal deve ser escapada. Ambos
\\"
e\\\"
funcionam.Citação de
escape e barra invertida em / G: FILE seqüências de pesquisa de regex Esse é o caso em que as seqüências de escape funcionam conforme o esperado com base na documentação. Quote não é um metacaractere regex, portanto, não precisa ser escapado (mas pode ser). A barra invertida é um metacaractere de expressão regular, portanto deve ser escapada.
Limites de caracteres para parâmetros da linha de comandos - transformação ASCII estendida
O caractere nulo (0x00) não pode aparecer em nenhuma sequência na linha de comandos. Qualquer outro caractere de byte único pode aparecer na sequência (0x01 - 0xFF). No entanto, o FINDSTR converte muitos caracteres ASCII estendidos encontrados nos parâmetros da linha de comando em outros caracteres. Isso tem um grande impacto de duas maneiras:
1) Muitos caracteres ASCII estendidos não corresponderão se forem usados como uma sequência de pesquisa na linha de comando. Essa limitação é a mesma para pesquisas literais e regex. Se uma sequência de pesquisa precisar conter ASCII estendido, o comando
/G:FILE
opção deverá ser usada.2) O FINDSTR pode falhar ao encontrar um arquivo se o nome contiver caracteres ASCII estendidos e o nome do arquivo for especificado na linha de comando. Se um arquivo a ser pesquisado contiver ASCII estendido no nome, a
/F:FILE
opção deverá ser usada.Aqui está uma lista completa das transformações de caracteres ASCII estendidas que o FINDSTR executa nas seqüências de caracteres da linha de comando. Cada caractere é representado como o valor do código de bytes decimais. O primeiro código representa o caractere conforme fornecido na linha de comando e o segundo código representa o caractere no qual ele é transformado. Nota - esta lista foi compilada em uma máquina nos EUA. Não sei qual o impacto que outros idiomas podem ter nessa lista.
Qualquer caractere> 0 que não esteja na lista acima é tratado como ele mesmo, incluindo
<CR>
e <LF>
. A maneira mais fácil de incluir caracteres ímpares como<CR>
e<LF>
é colocá-los em uma variável de ambiente e usar a expansão atrasada no argumento da linha de comando.Limites de caracteres para cadeias encontradas em arquivos especificados pelas opções / G: FILE e / F: FILE
O caractere nul (0x00) pode aparecer no arquivo, mas funciona como o terminador de cadeia C. Qualquer caractere após um caracter nulo é tratado como uma sequência diferente, como se estivesse em outra linha.
Os caracteres
<CR>
e<LF>
são tratados como terminadores de linha que terminam uma sequência e não são incluídos na sequência.Todos os outros caracteres de byte único são incluídos perfeitamente em uma string.
Pesquisando arquivos Unicode O
FINDSTR não pode pesquisar corretamente a maioria dos Unicode (UTF-16, UTF-16LE, UTF-16BE, UTF-32) porque não é possível procurar bytes nulos e o Unicode normalmente contém muitos bytes nulos.
No entanto, o comando TYPE converte UTF-16LE com BOM em um conjunto de caracteres de byte único; portanto, um comando como o seguinte funcionará com UTF-16LE com BOM.
Observe que os pontos de código Unicode que não são suportados pela sua página de código ativa serão convertidos em
?
caracteres.É possível pesquisar em UTF-8 desde que sua string de pesquisa contenha apenas ASCII. No entanto, a saída do console de qualquer caractere UTF-8 de vários bytes não estará correta. Mas se você redirecionar a saída para um arquivo, o resultado será codificado corretamente em UTF-8. Observe que, se o arquivo UTF-8 contiver uma BOM, ela será considerada como parte da primeira linha, o que poderia desencadear uma pesquisa que corresponda ao início de uma linha.
É possível pesquisar caracteres UTF-8 de bytes múltiplos, se você colocar a sequência de caracteres de pesquisa em um arquivo de pesquisa codificado em UTF-8 (sem BOM) e usar a opção / G.
Fim da linha
FINDSTR quebra as linhas imediatamente após cada <LF>. A presença ou ausência de <CR> não afeta as quebras de linha.
Pesquisando Quebra de Linha
Como esperado, o
.
metacaractere regex não corresponderá a <CR> ou <LF>. Mas é possível pesquisar em uma quebra de linha usando uma string de pesquisa de linha de comando. Os caracteres <CR> e <LF> devem ser correspondidos explicitamente. Se uma correspondência de várias linhas for encontrada, apenas a 1ª linha da correspondência será impressa. O FINDSTR então volta para a segunda linha da fonte e inicia a busca novamente - uma espécie de recurso do tipo "olhar à frente".Suponha que TEXT.TXT tenha esse conteúdo (pode ser do estilo Unix ou Windows)
Então este script
dá esses resultados
A pesquisa nas quebras de linha usando a opção / G: FILE é imprecisa porque a única maneira de corresponder a <CR> ou <LF> é através de uma expressão de intervalo de classe de caracteres regex que imprensa os caracteres EOL.
[<TAB>-<0x0B>]
corresponde a <LF>, mas também corresponde a <TAB> e <0x0B>[<0x0C>-!]
corresponde a <CR>, mas também a <0x0C> e!Nota - as representações acima são simbólicas do fluxo de bytes regex, pois não posso representar graficamente os caracteres.
A resposta continua na parte 2 abaixo ...
fonte
addpath.bat
do Q141344 e do findstr, que pode estar relacionado ao problema de suspensão do Win7 mencionado acima. Eu criei uma sala de chat para tentar controlar isso para baixo, para qualquer pessoa interessada: chat.stackoverflow.com/rooms/13177/.../S
e/D
opções decorrentes de nomes curtos de arquivo 8.3.<LF>
A resposta continuou da parte 1 acima - eu atingi o limite de resposta de 30.000 caracteres :-(
Suporte
para expressões regulares limitadas (regex) O suporte do FINDSTR para expressões regulares é extremamente limitado. Se não estiver na documentação da AJUDA, não há suporte.
Além disso, as expressões regex suportadas são implementadas de maneira completamente fora do padrão, de modo que os resultados podem ser diferentes do que seria esperado, vindo de algo como grep ou perl.
As âncoras de posição da linha Regex ^ e $
^
correspondem ao início do fluxo de entrada, bem como a qualquer posição imediatamente após um <LF>. Como o FINDSTR também quebra as linhas após <LF>, uma simples expressão regular de "^" sempre corresponderá a todas as linhas de um arquivo, mesmo um arquivo binário.$
corresponde a qualquer posição imediatamente anterior a um <CR>. Isso significa que uma sequência de pesquisa de expressão regular que$
nunca corresponderá a nenhuma linha de um arquivo de texto no estilo Unix, nem corresponderá à última linha de um arquivo de texto do Windows se estiver faltando o marcador EOL de <CR> <LF>.Nota - Conforme discutido anteriormente, a entrada canalizada e redirecionada para o FINDSTR pode ter
<CR><LF>
acrescentado um anexo que não está na fonte. Obviamente, isso pode afetar uma pesquisa de regex usada$
.Qualquer string de pesquisa com caracteres antes
^
ou depois$
sempre falha em encontrar uma correspondência.Opções posicionais / B / E / X
As opções posicionais funcionam da mesma forma que
^
e$
, exceto que também funcionam para cadeias de pesquisa literais./ B funciona da mesma maneira que
^
no início de uma sequência de pesquisa de expressão regular./ E funciona da mesma forma que
$
no final de uma sequência de pesquisa de expressão regular./ X funciona da mesma forma que
^
no início e$
no final de uma sequência de pesquisa de expressão regular.O limite da palavra
\<
regex deve ser o primeiro termo na regex. A regex não corresponderá a nada se outros caracteres a precedem.\<
corresponde ao início da entrada, ao início de uma linha (a posição imediatamente após um <LF>) ou a posição imediatamente após qualquer caractere "não palavra". O próximo caractere não precisa ser um caractere "palavra".\>
deve ser o último termo na regex. O regex não corresponderá a nada se outros caracteres o seguirem.\>
corresponde ao final da entrada, à posição imediatamente anterior a um <CR> ou à posição imediatamente anterior a qualquer caractere "não palavra". O caractere anterior não precisa ser um caractere "palavra".Aqui está uma lista completa de caracteres "não-palavra", representados como o código de bytes decimais. Nota - esta lista foi compilada em uma máquina nos EUA. Não sei qual o impacto que outros idiomas podem ter nessa lista.
Intervalos de classes de caracteres regex [xy]
Os intervalos de classes de caracteres não funcionam conforme o esperado. Veja esta pergunta: Por que o findstr não lida com o caso corretamente (em algumas circunstâncias)? , junto com esta resposta: https://stackoverflow.com/a/8767815/1012053 .
O problema é que o FINDSTR não agrupa os caracteres pelo valor do código de bytes (geralmente considerado o código ASCII, mas o ASCII é definido apenas de 0x00 a 0x7F). A maioria das implementações de regex trataria [AZ] como todas as letras maiúsculas em inglês. Mas o FINDSTR usa uma sequência de agrupamento que corresponde aproximadamente à maneira como o SORT funciona. Portanto, [AZ] inclui o alfabeto completo em inglês, letras maiúsculas e minúsculas (exceto "a"), além de caracteres alfabéticos não ingleses com diacríticos.
Abaixo está uma lista completa de todos os caracteres suportados pelo FINDSTR, classificados na sequência de intercalação usada pelo FINDSTR para estabelecer intervalos de classes de caracteres regex. Os caracteres são representados como seu valor de código de bytes decimais. Acredito que a sequência de intercalação faz mais sentido se os caracteres forem visualizados usando a página de códigos 437. Nota - essa lista foi compilada em uma máquina nos EUA. Não sei qual o impacto que outros idiomas podem ter nessa lista.
Limite de termos da classe de caracteres de expressão regular e BUG O
FINDSTR não é limitado apenas a um máximo de 15 termos de classe de caracteres em uma expressão regular, mas falha ao lidar adequadamente com uma tentativa de exceder o limite. O uso de 16 ou mais termos de classe de caracteres resulta em um pop-up interativo do Windows informando "O utilitário Find String (QGREP) encontrou um problema e precisa fechar. Desculpe-nos pela inconveniência." O texto da mensagem varia um pouco, dependendo da versão do Windows. Aqui está um exemplo de um FINDSTR que falhará:
Esse bug foi relatado pelo usuário do DosTips Judago aqui . Foi confirmado no XP, Vista e Windows 7.
As pesquisas de
regex falham (e podem travar indefinidamente) se incluirem o código de byte 0xFF (decimal 255) Qualquer pesquisa de regex que inclua o código de byte 0xFF (decimal 255) falhará. Falha se o código de byte 0xFF for incluído diretamente ou implicitamente estiver incluído em um intervalo de classe de caracteres. Lembre-se de que os intervalos da classe de caracteres FINDSTR não agrupam caracteres com base no valor do código de bytes. O caractere
<0xFF>
aparece relativamente cedo na sequência de intercalação entre os caracteres<space>
e<tab>
. Portanto, qualquer intervalo de classe de personagem que inclua os dois<space>
e<tab>
falhe.O comportamento exato muda um pouco, dependendo da versão do Windows. O Windows 7 trava indefinidamente se 0xFF estiver incluído. O XP não trava, mas sempre falha ao encontrar uma correspondência e, ocasionalmente, imprime a seguinte mensagem de erro - "O processo tentou gravar em um canal inexistente".
Não tenho mais acesso a uma máquina Vista, portanto não pude testar no Vista.
Erro de
.
[^anySet]
regex : e pode corresponder ao final do arquivo O
.
meta-caractere regex deve corresponder apenas a qualquer caractere que não seja<CR>
ou<LF>
. Existe um erro que permite corresponder ao final do arquivo se a última linha do arquivo não for finalizada por<CR>
ou<LF>
. No entanto, o.
arquivo não corresponderá a um arquivo vazio.Por exemplo, um arquivo chamado "test.txt" contendo uma única linha de
x
, sem terminar<CR>
ou<LF>
, corresponderá ao seguinte:Este bug foi confirmado no XP e Win7.
O mesmo parece ser verdadeiro para conjuntos de caracteres negativos. Algo como
[^abc]
irá corresponder ao fim do arquivo. Conjuntos de caracteres positivos[abc]
parecem funcionar bem. Eu só testei isso no Win7.fonte
type
parafindstr
.findstr
suporta várias/c:
cadeias de pesquisa. Eu sei que suas respostas demonstram isso. Mas é algo que não está documentado; e fiquei bastante surpreso ao saber do recurso depois de usá-findstr
lo por alguns anos.LF
problema que você documentou. Percebi que meu arquivo de teste não terminouLF
porque useicopy
no modo de acréscimo para criá-lo. Eu coloquei uma sessão de linha de comando para demonstrar o problema em uma resposta ( stackoverflow.com/a/22943056/224704 ). Observe que a entrada não é redirecionada e, no entanto, a pesquisa trava. O mesmo comando de pesquisa exato não trava com arquivos menores que da mesma forma não terminamLF
.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 personagens) -ErrorLevel = -1073740791 (0xC0000409)
, a janela de diálogo de erro :Find String (QGREP) Utility has stopped working
; após a remoção de uma classe ou dois caracteres Meta (*\.
), ele funciona ...findstr
às vezes trava inesperadamente ao pesquisar arquivos grandes.Não confirmei as condições exatas ou os tamanhos dos limites. Eu suspeito que qualquer arquivo maior de 2 GB pode estar em risco.
Eu tive experiências mistas com isso, por isso é mais do que apenas o tamanho do arquivo. Parece que pode haver uma variação no FINDSTR travar no XP e no Windows 7 se a entrada redirecionada não terminar com LF , mas, como demonstrado, esse problema específico se manifesta quando a entrada não é redirecionada.
A seguinte sessão de linha de comando (Windows 7) demonstra como
findstr
travar ao pesquisar um arquivo de 3 GB.Observe que eu verifiquei em um editor hexadecimal que todas as linhas são encerradas
CRLF
. A única anomalia é que o arquivo é finalizado0x1A
devido ao modo comocopy
funciona . Observe, no entanto, que essa anomalia não causa problemas em arquivos "pequenos" .Com testes adicionais, confirmei o seguinte:
copy
da/b
opção para arquivos binários impede a adição do0x1A
caractere efindstr
não fica suspenso no arquivo de 3 GB.findstr
a paralise.0x1A
personagem não causa problemas em um arquivo "pequeno". (Da mesma forma para outros caracteres finais).CRLF
depois0x1A
resolve o problema. (LF
por si só provavelmente seria suficiente.)type
para canalizar o arquivo emfindstr
obras sem travar. (Isso pode ser devido a um efeito colateral de umtype
ou|
que insere um fim de linha adicional.)<
também causafindstr
travamento. Mas isso é esperado; como explicado no post do dbenham : "a entrada redirecionada deve terminar emLF
" .fonte
<LF>
. Um arquivo dois bytes menor não foi interrompido. Muito nojento!Quando vários comandos estão entre parênteses e há arquivos redirecionados para todo o bloco:
... os arquivos permanecerão abertos enquanto os comandos do bloco estiverem ativos, para que os comandos possam mover o ponteiro dos arquivos redirecionados. Os comandos MORE e FIND movem o ponteiro do arquivo Stdin para o início do arquivo antes de processá-lo, para que o mesmo arquivo possa ser processado várias vezes dentro do bloco. Por exemplo, este código:
... produz o mesmo resultado que este:
Este código:
... produz o mesmo resultado que este:
FINDSTR é diferente; ele não move o ponteiro do arquivo Stdin de sua posição atual. Por exemplo, esse código insere uma nova linha após uma linha de pesquisa:
Podemos fazer bom uso desse recurso com a ajuda de um programa auxiliar que nos permite mover o ponteiro do arquivo redirecionado, como mostra este exemplo .
Este comportamento foi primeiramente relatada por jeb a este post .
EDIT 2018-08-18 : Novo bug do FINDSTR relatado
O comando FINDSTR possui um erro estranho que ocorre quando esse comando é usado para mostrar caracteres em cores E a saída desse comando é redirecionada para o dispositivo CON. Para obter detalhes sobre como usar o comando FINDSTR para mostrar texto em cores, consulte este tópico .
Quando a saída dessa forma de comando FINDSTR é redirecionada para CON, algo estranho acontece depois que o texto é exibido na cor desejada: todo o texto após ele é exibido como caracteres "invisíveis", embora uma descrição mais precisa seja o texto. saída como texto em preto sobre fundo preto. O texto original será exibido se você usar o comando COLOR para redefinir as cores de primeiro e segundo plano da tela inteira. No entanto, quando o texto é "invisível", podemos executar um comando SET / P, para que todos os caracteres digitados não apareçam na tela. Esse comportamento pode ser usado para inserir senhas.
fonte
Eu gostaria de relatar um erro referente à seção Fonte de dados para pesquisar na primeira resposta ao usar en dash (-) ou em dash (-) dentro do nome do arquivo.
Mais especificamente, se você estiver prestes a usar a primeira opção - nomes de arquivos especificados como argumentos , o arquivo não será encontrado. Assim que você usar a opção 2 - stdin via redirecionamento ou 3 - fluxo de dados de um canal, o findstr encontrará o arquivo.
Por exemplo, este script em lote simples:
irá imprimir:
Nome do arquivo com traço:
Como argumento
FINDSTR: Não é possível abrir o nome do arquivo com - dash.txt
Como stdin via redirecionamento,
eu sou o arquivo com um traço.
Como fluxo de dados de um pipe,
eu sou o arquivo com um traço.
Nome do arquivo com em dash:
Como argumento
FINDSTR: Não é possível abrir o nome do arquivo com - dash.txt
Como stdin via redirecionamento,
eu sou o arquivo com um traço em.
Como fluxo de dados de um pipe,
eu sou o arquivo com um traço em.
Espero que ajude.
M.
fonte
O
findstr
comando define oErrorLevel
(ou código de saída) para um dos seguintes valores, dado que não há opções inválidas ou incompatíveis e nenhuma cadeia de pesquisa excede o limite de comprimento aplicável:0
quando pelo menos uma única correspondência for encontrada em uma linha em todos os arquivos especificados;1
de outra forma;Uma linha é considerada como contendo uma correspondência quando:
/V
opção é fornecida e a expressão de pesquisa ocorre pelo menos uma vez;/V
opção é dada e a expressão de pesquisa não ocorre;Isso significa que a
/V
opção também altera a retornadaErrorLevel
, mas não apenas a reverte!Por exemplo, quando você tem um arquivo
test.txt
com duas linhas, uma das quais contém a sequência,text
mas a outra não, ambasfindstr "text" "test.txt"
efindstr /V "text" "test.txt"
retorna umErrorLevel
de0
.Basicamente, você pode dizer: se
findstr
retorna pelo menos uma linha,ErrorLevel
está definido como0
, caso contrário, para1
.Observe que a
/M
opção não afeta oErrorLevel
valor, apenas altera a saída.(Apenas por uma questão de integridade: o
find
comando se comporta exatamente da mesma maneira com relação à/V
opção eErrorLevel
; a/C
opção não afetaErrorLevel
.)fonte
O FINDSTR possui um erro de cor que descrevi e resolvi em /superuser/1535810/is-there-a-better-way-to-mitigate-this-obscure-color-bug-when-piping-to -findstr / 1538802? noredirect = 1 # comment2339443_1538802
Para resumir esse segmento, o erro é que, se a entrada é canalizada para FINDSTR dentro de um bloco de código entre parênteses, os códigos de cores de escape ANSI embutidos param de funcionar nos comandos executados posteriormente. Um exemplo de códigos de cores embutidos é:
echo %magenta%Alert: Something bad happened%yellow%
(onde magenta e amarelo são vars definidos anteriormente no arquivo .bat como os códigos de cores de escape ANSI correspondentes).Minha solução inicial foi chamar uma sub-rotina do-nothing após o FINDSTR. De alguma forma, a chamada ou o retorno "redefine" o que precisar ser redefinido.
Mais tarde, descobri outra solução que presumivelmente é mais eficiente: coloque a frase FINDSTR entre parênteses, como no exemplo a seguir:
echo success | ( FINDSTR /R success )
Colocar a frase FINDSTR em um bloco de código aninhado parece isolar o bug do código de cores do FINDSTR para que não afete o que está fora do aninhado quadra. Talvez essa técnica resolva outros efeitos colaterais indesejados do FINDSTR também .fonte
/ D dica para vários diretórios: coloque sua lista de diretórios antes da string de pesquisa. Tudo isso funciona:
Como esperado, o caminho é relativo ao local se você não iniciar os diretórios com
\
. Rodear o caminho com"
é opcional se não houver espaços nos nomes dos diretórios. O final\
é opcional. A saída do local incluirá qualquer caminho que você indicar. Ele funcionará com ou sem cercar a lista de diretórios com"
.fonte
/D:dirlist Search a semicolon-delimited list of directories
e é colocada antes da sequência de pesquisa, por isso não entendo exatamente o que "você encontrou" sobre a opção / D (e quais são os "comandos" não funciona ") ...findstr
listas / D primeiro. Sim, não tenho argumentos com o recurso sendo documentado, apenas não está documentado sobre o problema que importa a ordem dos atributos. Como faço muito pouco trabalho de linha de comando, portanto, quando eu estava executando um comando, sem perceber que a ordem fazia diferença, estava apenas adicionando os atributos conforme cheguei a eles (e em ordem alfabética, C precede D). Fiquei muito frustrado e compartilhei minha experiência "encontrada" para qualquer pessoa que não trabalhe muito com a linha de comando.findstr
documentação especifica que astrings
parte NÃO é opcional e que você deve colocá-la após os atributos opcionais e antes da lista de nome de arquivo opcional . Se "o que você encontrou" é que o uso de um comando sem seguir seu formato de uso causa um erro, esse ponto está bem documentado. Consulte Sintaxe de comando : "A sintaxe aparece na ordem em que você deve digitar um comando e todos os parâmetros que o seguem"