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.
FINDSTR "^" FILE >FILE_COPY
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)
- 0 (sucesso)
- A correspondência foi encontrada em pelo menos uma linha de pelo menos um arquivo.
- 1 (falha)
- Não foi encontrada nenhuma correspondência em nenhuma linha de nenhum arquivo.
- Cor inválida especificada pela
/A:xx
opção
- 2 (erro)
- Opções incompatíveis
/L
e /R
ambas especificadas
- Faltando argumento após
/A:
, /F:
, /C:
, /D:
, ou/G:
- Arquivo especificado por
/F:file
ou /G:file
não encontrado
- 255 (erro)
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ção
stdin 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ção
Os 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ções
Tal 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:
b1.txt
b.txt2
c.txt
O comando a seguir encontrará com êxito todos os 3 arquivos:
findstr /m "^" *.txt
b.txt2
corresponde porque o nome abreviado correspondente B9F64~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
findstr /m /d:. "^" *.txt
findstr /m /s "^" *.txt
O erro evita que b.txt2
seja encontrado, assim como todos os nomes de arquivos que são classificados b.txt2
no mesmo diretório. Arquivos adicionais que são classificados antes, como a.txt
, são encontrados. Arquivos adicionais que são classificados mais tarde, como d.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, mas c.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ção
A /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:
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 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>
anexada
Se 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.
> set /p "=x" <nul | findstr "^"
> set /p "=xx" <nul | findstr "^"
xx
> echo x| findstr "^"
x
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 no FINDSTR: 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.
echo ffffaaa|findstr /l "ffffaaa faffaffddd"
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:
- A pesquisa está usando várias cadeias de pesquisa literais
- As cadeias de pesquisa têm diferentes comprimentos
- Uma cadeia de pesquisa curta possui uma certa quantidade de sobreposição com uma cadeia de pesquisa mais longa
- A pesquisa diferencia maiúsculas de minúsculas (sem
/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?
Citações e retrocessos nos argumentos da linha de comando
Nota - Os comentários do usuário MC ND refletem as regras realmente terrivelmente complicadas para esta seção. Existem três fases de análise distintas envolvidas:
- O primeiro cmd.exe pode exigir que algumas aspas sejam escapadas como ^ "(realmente nada a ver com FINDSTR)
- O próximo FINDSTR usa o analisador de argumentos anterior ao MS C / C ++ 2008 , que possui regras especiais para "e \
- Depois que o analisador de argumentos termina, o FINDSTR trata adicionalmente \ seguido por um caractere alfanumérico como literal, mas \ seguido por um caractere não alfanumérico como caractere de escape
O restante desta seção destacada não está 100% correto. Pode servir como um guia para muitas situações, mas as regras acima são necessárias para o entendimento total.
Escapando Citação nas cadeias de pesquisa da linha de comando As
cotas nas cadeias de pesquisa da linha de comando devem ser escapadas com uma barra invertida
\"
. Isso é verdade para as cadeias de pesquisa literal e regex. Esta informação foi confirmada no XP, Vista e Windows 7.
Nota: A cotação também pode precisar ser escapada para o analisador CMD.EXE, mas isso não tem nada a ver com FINDSTR. Por exemplo, para procurar uma única citação, você pode usar:
FINDSTR \^" file && echo found || echo not found
Escapando a barra invertida nas cadeias de pesquisa literais da linha de comando A
barra invertida em uma cadeia de pesquisa literal pode normalmente ser representada como
\
ou como \\
. Eles são tipicamente equivalentes. (Pode haver casos incomuns no Vista em que a barra invertida sempre deve ser escapada, mas eu não tenho mais uma máquina do Vista para testar) .
Mas existem alguns casos especiais:
Ao procurar barras invertidas consecutivas, todas, exceto a última, devem ser escapadas. A última barra invertida pode opcionalmente ser escapada.
\\
pode ser codificado como \\\
ou\\\\
\\\
pode ser codificado como \\\\\
ou\\\\\\
A pesquisa de uma ou mais barras invertidas antes de uma cotação é bizarra. A lógica sugere que a cotação deve ser escapada, e cada uma das barras invertidas principais precisaria ser escapada, mas isso não funciona! Em vez disso, cada uma das barras invertidas principais deve ter escape duplo e a citação é escapada normalmente:
\"
deve ser codificado como \\\\\"
\\"
deve ser codificado como \\\\\\\\\"
Como observado anteriormente, uma ou mais cotações de escape também podem exigir escape ^
para o analisador de CMD
As informações nesta seção foram confirmadas no XP e Windows 7.
Escapando barra invertida nas cadeias de pesquisa de expressão regular da linha de comandos
Apenas Vista: a barra invertida em uma regex deve ter escape duplo como \\\\
, ou escape único em uma classe de caracteres definida como
[\\]
XP e Windows 7: a barra invertida em uma regex sempre pode ser representada como [\\]
. Normalmente pode ser representado como \\
. Mas isso nunca funciona se a barra invertida preceder uma cotação de escape.
Uma ou mais barras invertidas antes de uma cotação de escape devem ser de escape duplo ou codificadas como [\\]
\"
pode ser codificado como \\\\\"
ou[\\]\"
\\"
pode ser codificado como \\\\\\\\\"
ou [\\][\\]\"
ou\\[\\]\"
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.
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
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.
type unicode.txt|findstr "search"
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)
A
A
A
B
A
A
Então 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
dá esses resultados
1:A
2:A
5:A
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 ...
grep
que é muito bem entendido e documentado :-) Veja stackoverflow.com/questions/2635740/… por exemplo.