Windows FINDSTR 명령의 문서화되지 않은 기능 및 제한 사항은 무엇입니까?


188

Windows FINDSTR 명령은 끔찍하게 문서화되어 있습니다. 이 아주 기본적인 명령 줄 도움말을 사용할 수를 통해입니다 FINDSTR /?, 또는 HELP FINDSTR, 그러나 그것은 비참하게 부족하다. https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr에 온라인으로 더 많은 문서가 있습니다 .

문서에서 암시하지 않은 많은 FINDSTR 기능과 제한 사항이 있습니다. 사전 지식이나 신중한 실험 없이는 기대할 수 없었습니다.

따라서 문제는- 문서화되지 않은 FINDSTR 기능과 제한은 무엇입니까?

이 질문의 목적은 다음과 같이 문서화되지 않은 많은 기능의 원 스톱 저장소를 제공하는 것입니다.

A) 개발자는 존재하는 기능을 최대한 활용할 수 있습니다.

B) 개발자는 왜 무언가가 제대로 작동하지 않는지 궁금해하는 데 시간을 낭비하지 않습니다.

응답하기 전에 기존 문서를 알고 있는지 확인하십시오. 정보가 HELP에 포함되어 있으면 여기에 속하지 않습니다.

FINDSTR의 흥미로운 사용법을 보여주는 곳도 아닙니다. 논리적 인 사람이 문서를 기반으로 특정 FINDSTR 사용의 동작을 예상 할 수 있으면 여기에 속하지 않습니다.

동일한 행을 따라 논리적 사람이 기존 답변에 포함 된 정보를 기반으로 특정 사용의 동작을 예상 할 수 있으면 다시 여기에 속하지 않습니다.


15
또는, 양자 택일로, 당신은 전부 엉터리 문서화되지 않은 MS 유틸리티 도랑 수 있으며, 설치 / 사용 되는 매우 잘 이해하고 문서화 :-) 참조 stackoverflow.com/questions/2635740/...을 예를 들어 있습니다. grep
paxdiablo

17
꼭 FINDSTR 이외의 다른 것을 사용할 수 있다면, 그것은 매우 좋습니다. 그러나 일부 사람들은 타사 유틸리티가 금지 된 환경에 있습니다.
dbenham

4
공격이 없습니다. 나는 당신의 의견과 비슷한 내 자신의 FINDSTR 고지 사항을 넣는 것을 진지하게 고려했습니다! :)
dbenham 2019 년

41
나는 충격을 받고 실망했다. 누군가가이 질문을 "비 건축 적"이라고 생각하고 닫으려고 투표 할 것이다. "의견, 토론, 논쟁, 여론 조사, 또는 확장 된 토론"을 피하기 위해 많은 생각이 제기되었습니다. 이 질문은 3.5 개월 동안 게시되었으며, 언급 된 부정적인 결과는 없습니다. 한 쌍의 답변은 사실로 가득 차 있으며 많은 시간과 노력이 필요합니다.
dbenham

6
일부 독자는 FINDSTR 명령의 역사적 맥락에 관심이있을 수 있습니다 : blogs.msdn.com/b/oldnewthing/archive/2012/11/28/10372436.aspx
해리 존스턴을

답변:


279

서문
이 답변의 많은 정보는 Vista 시스템에서 실행 된 실험을 기반으로 수집되었습니다. 명시 적으로 달리 명시하지 않는 한, 정보가 다른 Windows 버전에 적용되는지 확인하지 않았습니다.

FINDSTR 출력
이 문서는 FINDSTR의 출력을 설명 할 필요가 없습니다. 일치하는 줄이 인쇄된다는 사실을 암시하지만 더 이상은 없습니다.

일치하는 라인 출력 형식은 다음과 같습니다.

filename : lineNumber : lineOffset : 텍스트

어디

fileName : = 일치하는 줄을 포함하는 파일 이름. 요청이 단일 파일에 대한 명시 적이거나 파이프 입력 또는 경로 재 지정된 입력을 검색하는 경우 파일 이름이 인쇄되지 않습니다. 인쇄 될 때, fileName은 항상 제공된 경로 정보를 포함합니다. /S옵션을 사용하면 추가 경로 정보가 추가됩니다. 인쇄 된 경로는 항상 제공된 경로를 기준으로하거나 제공된 디렉토리가없는 경우 현재 디렉토리를 기준으로합니다.

주 - 사용하여 여러 파일을 검색 할 때 파일 이름 접두어가 피할 수 비표준 (그리고 제대로 문서화) 와일드 카드 <>. 이러한 와일드 카드 작동 방식에 대한 정확한 규칙은 여기에서 확인할 수 있습니다 . 마지막으로 비표준 와일드 카드가 FINDSTR과 함께 작동하는 방법에 대한예제를 볼 수 있습니다 .

lineNumber : = 입력의 첫 번째 행을 나타내는 1과 함께 10 진수 값으로 표시되는 일치하는 행의 행 번호입니다. /N옵션이 지정된경우에만 인쇄됩니다.

lineOffset : = 일치하는 줄 시작 부분의 10 진수 바이트 오프셋. 0은 첫 번째 줄의 첫 번째 문자를 나타냅니다. /O옵션이 지정된경우에만 인쇄됩니다. 이것은라인 내에서 일치하는 오프셋이 아닙니다 . 파일의 시작부터 행의 시작까지의 바이트 수입니다.

text = <CR> 및 / 또는 <LF>를 포함하여 일치하는 줄의 이진 표현입니다. 모든 행과 일치하는이 예제는 원본 파일의 정확한 이진 사본을 생성하도록 이진 출력에서 ​​제외되는 것은 없습니다.

FINDSTR "^" FILE >FILE_COPY

/ A 옵션은 fileName :, lineNumber : 및 lineOffset : 출력의 색상 만 설정합니다. 일치하는 줄의 텍스트는 항상 현재 콘솔 색상으로 출력됩니다. / A 옵션은 출력이 콘솔에 직접 표시 될 때만 적용됩니다. 출력이 파일로 경로 재 지정되거나 파이프 된 경우 / A 옵션은 적용되지 않습니다. 출력이 CON으로 리디렉션 될 때 버기 동작에 대한 설명은 Aacini의 답변에서 2018-08-18 편집을 참조하십시오 .

XP에서 대부분의 제어 문자 및 많은 확장 ASCII 문자가 도트로 표시 XP의
FINDSTR은 화면에서 일치하는 행의 대부분의 인쇄 불가능 제어 문자를 도트 (마침표)로 표시합니다. 다음 제어 문자는 예외입니다. 0x09 탭, 0x0A LineFeed, 0x0B 세로 탭, 0x0C 용지 공급, 0x0D 캐리지 리턴으로 표시됩니다.

XP FINDSTR은 또한 다수의 확장 ASCII 문자를 도트로 변환합니다. XP에서 점으로 표시되는 확장 ASCII 문자는 명령 행에서 제공 될 때 변환 된 것과 동일합니다. 참고 항목 "명령 줄 매개 변수에 대한 문자 제한을 - 확장 ASCII 변환" 나중에 섹션을,이 게시물에

출력이 파이프되거나 파일로 경로 재 지정되거나 FOR IN () 절 내에서 제어 문자 및 확장 ASCII는 XP에서 도트로 변환되지 않습니다.

Vista 및 Windows 7은 항상 모든 문자를 점으로 표시하지 않고 항상 그대로 표시합니다.

리턴 코드 (ERRORLEVEL)

검색 할 데이터 소스 (Windows 7 테스트를 기반으로 업데이트 됨)
Findstr은 다음 소스 중 하나에서만 데이터를 검색 할 수 있습니다.

  • 인수로 및 / 또는 /F:file옵션을 사용하여 지정된 파일 이름 .

  • 리디렉션을 통한 표준 입력 findstr "searchString" <file

  • 파이프에서 데이터 스트림 type file | findstr "searchString"

인수 / 옵션은 리디렉션보다 우선하며 파이프 된 데이터보다 우선합니다.

파일 이름 인수와 /F:file결합 될 수 있습니다. 여러 파일 이름 인수를 사용할 수 있습니다. 여러 /F:file옵션을 지정하면 마지막 옵션 만 사용됩니다. 와일드 카드는 파일 이름 인수에 사용할 수 있지만로 가리키는 파일에는 사용할 수 없습니다 /F:file.

검색 문자열의 소스는 (Windows 7과 테스트를 기반으로 업데이트) 및 옵션이 결합 될 수있다. 여러 옵션을 지정할 수 있습니다. 여러 옵션을 지정하면 마지막 옵션 만 사용됩니다. 또는 중 하나 를 사용하는 경우 모든 비 옵션 인수는 검색 할 파일로 간주됩니다. nor 도 사용 하지 않으면 첫 번째 비 옵션 인수는 공백으로 구분 된 검색어 목록으로 처리됩니다.
/G:file/C:string/C:string/G:file/G:file/C:string/G:file/C:string

/F:FILE옵션을 사용할 때 파일 내에서 파일 이름을 인용해서는 안됩니다 .
파일 이름에는 공백과 기타 특수 문자가 포함될 수 있습니다. 대부분의 명령에서는 그러한 파일 이름을 인용해야합니다. 그러나 FINDSTR /F:files.txt옵션을 사용하려면 files.txt 내의 파일 이름을 인용해서는 안됩니다. 이름이 인용되면 파일을 찾을 수 없습니다.

BUG-짧은 8.3 파일 이름으로 인해 /D/S옵션이 손상 될 수
있음 모든 Windows 명령과 마찬가지로 FINDSTR은 검색 할 파일을 찾을 때 긴 이름과 짧은 8.3 이름을 모두 일치시킵니다. 현재 폴더에 비어 있지 않은 다음 파일이 포함되어 있다고 가정합니다.

b1.txt
b.txt2
c.txt

다음 명령은 3 개의 파일을 모두 찾습니다.

findstr /m "^" *.txt

b.txt2해당 짧은 이름이 일치하기 때문에 B9F64~1.TXT일치합니다. 이것은 다른 모든 Windows 명령의 동작과 일치합니다.

그러나 /D/S옵션 의 버그로 인해 다음 명령 만 찾을 수 있습니다.b1.txt

findstr /m /d:. "^" *.txt
findstr /m /s "^" *.txt

버그 는 같은 디렉토리 내에서 b.txt2정렬 된 모든 파일 이름뿐만 아니라 찾을 수 없습니다 b.txt2. 이전과 같이 정렬하는 추가 파일이 a.txt있습니다. d.txt버그가 트리거되면 나중에 정렬하는 추가 파일 이 누락됩니다.

검색된 각 디렉토리는 독립적으로 취급됩니다. 예를 들어, /S옵션은 상위에서 파일을 찾지 못한 후 하위 폴더에서 성공적으로 검색을 시작하지만, 버그로 인해 하위에서 짧은 파일 이름이 누락되면 해당 하위 폴더의 모든 후속 파일도 누락됩니다. .

NTFS 8.3 이름 생성이 비활성화 된 컴퓨터에서 동일한 파일 이름을 만들면 명령이 버그없이 작동합니다. 물론 b.txt2찾을 수는 없지만 c.txt올바르게 찾을 수 있습니다.

짧은 이름이 모두 버그를 유발하는 것은 아닙니다. 내가 본 버그가있는 동작의 모든 인스턴스에는 8.3 이름이 필요하지 않은 일반 이름과 동일하게 시작되는 짧은 8.3 이름을 가진 3 자보다 긴 확장명이 포함됩니다.

XP, Vista 및 Windows 7에서 버그가 확인되었습니다.

인쇄 할 수없는 문자 및 /P옵션
/P옵션을 사용하면 FINDSTR이 다음 10 진수 바이트 코드 (
0-7, 14-25, 27-31) 를 포함하는 파일을 건너 뜁니다 .

달리 말하면, /P옵션은 인쇄 할 수없는 제어 문자가 포함 된 파일 만 건너 뜁니다. 제어 문자는 31 (0x1F) 이하의 코드입니다. FINDSTR은 다음 제어 문자를 인쇄 가능한 것으로 취급합니다.

 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)

다른 모든 제어 문자는 인쇄 할 수없는 것으로 취급되며 이로 인해 /P옵션이 파일을 건너 뜁니다.

파이프 및 리디렉션 입력이 <CR><LF>추가 되었을 수 있음
입력이 파이프되고 스트림의 마지막 문자가 아닌 <LF>경우 FINDSTR이 자동으로 <CR><LF>입력에 추가 됩니다. 이것은 XP, Vista 및 Windows 7에서 확인되었습니다. (Windows 파이프가 입력을 수정했다고 생각했지만 FINDSTR이 실제로 수정하고 있음을 알게되었습니다.)

Vista에서 리디렉션 된 입력의 경우에도 마찬가지입니다. 경로 재 지정된 입력으로 사용 된 파일의 마지막 문자가 아닌 <LF>경우 FINDSTR은 자동으로 <CR><LF>입력에 추가 합니다. 그러나 XP 및 Windows 7은 리디렉션 된 입력을 변경하지 않습니다.

리디렉션 된 입력이 다음으로 끝나지 않으면 FINDSTR이 XP 및 Windows 7에서 중단됨 XP 및 Windows 7<LF>
에서 불쾌한 "기능"입니다. 리디렉션 된 입력으로 사용 된 파일의 마지막 문자가로 끝나지 않으면 <LF>FINDSTR은 한 번 무한정 중단됩니다. 리디렉션 된 파일의 끝에 도달합니다.

파이프 된 데이터의 마지막 행이 단일 문자로 구성된 경우 무시 될 수 있습니다
. 입력이 파이프되고 마지막 행이 뒤에 오지 않는 단일 문자로 구성된 <LF>경우 FINDSTR은 마지막 행을 완전히 무시합니다.

예-단일 문자가없고 첫 번째 명령이 <LF>일치 하지 않지만 두 문자가있는 두 번째 명령은 줄 바꿈으로 끝나는 문자가 하나 인 세 번째 명령과 마찬가지로 제대로 작동합니다.

> set /p "=x" <nul | findstr "^"

> set /p "=xx" <nul | findstr "^"
xx

> echo x| findstr "^"
x

새로운 findstr 버그 에서 DosTips 사용자 Sponge Belly가보고했습니다 . XP, Windows 7 및 Windows 8에서 확인되었습니다. 아직 Vista에 대해 들어 보지 못했습니다. 더 이상 Vista를 테스트 할 필요가 없습니다.

옵션 구문
옵션 중 하나를 접두사로 할 수 /또는 - 옵션은 단일 후 연결될 수 있습니다 /또는 -. 그러나 연결된 옵션 목록에는 OFF 또는 F :와 같은 하나 이상의 다중 문자 옵션이 포함될 수 있으며 다중 문자 옵션은 목록의 마지막 옵션이어야합니다.

다음은 순서대로 "hello"와 "bybye"를 모두 포함하는 라인에 대해 대소 문자를 구분하지 않는 정규식 검색을 표현하는 동등한 방법입니다.

  • /i /r /c:"hello.*goodbye" /c:"goodbye.*hello"

  • -i -r -c:"hello.*goodbye" /c:"goodbye.*hello"

  • /irc:"hello.*goodbye" /c:"goodbye.*hello"

검색 문자열 길이 제한
Vista에서 단일 검색 문자열에 허용되는 최대 길이는 511 바이트입니다. 검색 문자열이 511을 초과하면 FINDSTR: Search string too long.ERRORLEVEL 2에 오류가 발생합니다.

정규식 검색을 수행 할 때 최대 검색 문자열 길이는 254입니다. 길이가 255에서 511 사이 인 정규식 FINDSTR: Out of memory은 ERRORLEVEL 2에서 FINDSTR: Search string too long.오류를 발생시킵니다. 정규식 길이가> 511이면 오류가 발생합니다.

Windows XP에서는 검색 문자열 길이가 훨씬 짧습니다. Findstr 오류 : "검색 문자열이 너무 깁니다": "for"루프에서 하위 문자열을 추출하고 일치시키는 방법은 무엇입니까? 리터럴 검색과 정규식 검색 모두에서 XP 제한은 127 바이트입니다.

줄 길이 제한
명령 줄 인수 또는 / F : FILE 옵션을 통해 지정된 파일에는 알려진 줄 길이 제한이 없습니다. 단일 <LF>를 포함하지 않은 128MB 파일에 대해 검색이 성공적으로 실행되었습니다.

파이프 데이터 및 경로 재 지정 입력은 라인 당 8191 바이트로 제한됩니다. 이 한계는 FINDSTR의 "기능"입니다. 파이프 나 리디렉션에는 고유하지 않습니다. 경로 재 지정된 stdin 또는 파이프 입력을 사용하는 FINDSTR은> = 8k 바이트 인 라인과 절대 일치하지 않습니다. 행> = 8k는 stderr에 오류 메시지를 생성하지만, 검색 문자열이 하나 이상의 파일의 하나 이상의 행에있는 경우 ERRORLEVEL은 여전히 ​​0입니다.

기본 검색 유형 : 리터럴 대 정규 표현식
/C:"string" -기본값은 / L 리터럴입니다. / L 옵션과 / C : "string"을 명시 적으로 결합하면 확실히 작동하지만 중복됩니다.

"string argument"-기본값은 첫 번째 검색 문자열의 내용에 따라 다릅니다. <문자열>은 검색 문자열을 구분하는 데 사용됩니다. 첫 번째 검색 문자열이 하나 이상의 이스케이프되지 않은 메타 문자를 포함하는 유효한 정규식 인 경우 모든 검색 문자열은 정규식으로 처리됩니다. 그렇지 않으면 모든 검색 문자열이 리터럴로 취급됩니다. 예를 들어 "51.4 200"첫 번째 문자열에는 이스케이프되지 않은 점이 포함되어 있기 때문에 두 개의 정규식으로 처리되는 반면 "200 51.4"첫 번째 문자열에는 메타 문자가 포함되지 않으므로 두 개의 리터럴로 취급됩니다.

/G:file-기본값은 파일에서 비어 있지 않은 첫 번째 줄의 내용에 따라 다릅니다. 첫 번째 검색 문자열이 이스케이프되지 않은 메타 문자를 하나 이상 포함하는 유효한 정규식 인 경우 모든 검색 문자열은 정규식으로 처리됩니다. 그렇지 않으면 모든 검색 문자열이 리터럴로 취급됩니다.

권장 사항 - 항상 명시 적으로 지정 /L문자 옵션 또는 /R사용하는 경우 정규 표현식 옵션을 "string argument"하거나 /G:file.

BUG-여러 리터럴 검색 문자열을 지정하면 신뢰할 수없는 결과를 얻을 수 있습니다

다음의 간단한 FINDSTR 예제는 일치하더라도 일치하는 항목을 찾지 못합니다.

echo ffffaaa|findstr /l "ffffaaa faffaffddd"

이 버그는 Windows Server 2003, Windows XP, Vista 및 Windows 7에서 확인되었습니다.

실험에 따라 다음 조건이 모두 충족되면 FINDSTR이 실패 할 수 있습니다.

  • 검색시 여러 리터럴 검색 문자열을 사용하고 있습니다
  • 검색 문자열의 길이가 다릅니다
  • 짧은 검색 문자열은 긴 검색 문자열과 어느 정도 겹칩니다.
  • 검색은 대소 문자를 구분합니다 ( /I옵션 없음 ).

내가 본 모든 실패에서, 그것은 항상 실패하는 더 짧은 검색 문자열 중 하나입니다.

자세한 내용은 리터럴 검색 문자열이 여러 개인이 FINDSTR 예제가 일치하지 않는 이유는 무엇입니까?를 참조하십시오 .

명령 줄 인수 내 따옴표 및 백 슬래시
참고 -User MC ND의 의견은이 섹션에 대한 실제 끔찍한 규칙을 반영합니다. 다음과 같은 세 가지 고유 한 구문 분석 단계가 있습니다.

  • 첫 번째 cmd.exe는 ^ "로 이스케이프되기 위해 따옴표가 필요할 수 있습니다 (실제로 FINDSTR과는 관련이 없음)
  • 다음 FINDSTR은 2008 년 이전 MS C / C ++ 인수 구문 분석기 를 사용하며 "및 \
  • 인수 구문 분석기가 완료된 후 FINDSTR은 추가로 \ 다음에 영숫자 문자를 리터럴로 취급하지만 \ 뒤에 영숫자가 아닌 문자가 이스케이프 문자로 취급합니다.

강조 표시된 섹션의 나머지 부분이 100 % 정확하지 않습니다. 많은 상황에 대한 안내서 역할을 할 수 있지만 완전히 이해하려면 위의 규칙이 필요합니다.

명령 행 검색 문자열 내에서 이스케이프 인용 명령 행 검색 문자열
내에서 인용 부호는과 같이 백 슬래시로 이스케이프해야합니다 \". 리터럴 및 정규식 검색 문자열 모두에 해당됩니다. 이 정보는 XP, Vista 및 Windows 7에서 확인되었습니다.

참고 : CMD.EXE 구문 분석기의 경우 인용 부호를 이스케이프해야 할 수도 있지만 FINDSTR과는 관련이 없습니다. 예를 들어 작은 따옴표를 검색하려면 다음을 사용할 수 있습니다.

FINDSTR \^" file && echo found || echo not found

명령 행 리터럴 검색 문자열에서
백 슬래시 이스케이프 리터럴 검색 문자열의 백 슬래시는 일반적으로 \또는로 표시 될 수 있습니다 \\. 그것들은 일반적으로 동일합니다. Vista에서 백 슬래시를 항상 이스케이프해야하는 비정상적인 경우가있을 수 있지만 더 이상 테스트 할 Vista 컴퓨터가 없습니다 .

그러나 특별한 경우가 있습니다.

연속 백 슬래시를 검색 할 때는 마지막 백 슬래시를 제외한 모든 백 슬래시를 이스케이프 해야 합니다. 마지막 백 슬래시는 선택적으로 이스케이프 될 수 있습니다.

  • \\\\\또는 으로 코딩 할 수 있습니다\\\\
  • \\\\\\\\또는 으로 코딩 할 수 있습니다\\\\\\

따옴표 전에 하나 이상의 백 슬래시를 검색하는 것은 기괴합니다. 논리는 따옴표를 이스케이프해야하고 각 선행 백 슬래시를 이스케이프해야한다고 제안하지만 작동하지 않습니다! 대신, 각 역 슬래시는 이중 이스케이프되어야하며 따옴표는 정상적으로 이스케이프되어야합니다.

  • \" 로 코딩해야합니다 \\\\\"
  • \\" 로 코딩해야합니다 \\\\\\\\\"

앞서 언급 한 바와 같이, 하나 이상의 이스케이프 된 따옴표는 ^CMD 파서 로 이스케이프 처리해야 할 수도 있습니다.

이 섹션의 정보는 XP 및 Windows 7에서 확인되었습니다.

명령 행 정규식 검색 문자열 내 백 슬래시 이스케이프

  • Vista에만 해당 : 정규 표현식의 백 슬래시는와 같이 이중 이스케이프 \\\\되거나 다음과 같은 문자 클래스 세트에서 단일 이스케이프되어야합니다. [\\]

  • XP 및 Windows 7 : 정규식의 백 슬래시는 항상로 표시 될 수 있습니다 [\\]. 일반적으로로 표시 될 수 있습니다 \\. 그러나 백 슬래시가 이스케이프 된 따옴표 앞에 오는 경우에는 작동하지 않습니다.

    이스케이프 된 따옴표 앞의 하나 이상의 백 슬래시는 이중 이스케이프되거나 다음과 같이 코딩되어야합니다. [\\]

    • \"\\\\\"또는 로 코딩 될 수있다[\\]\"
    • \\"로 부호화 될 수있다 \\\\\\\\\"거나 [\\][\\]\"또는\\[\\]\"

/ G : FILE 리터럴 검색 문자열에서
따옴표 및 백 슬래시 이스케이프 / G : file에 지정된 리터럴 검색 문자열 파일 내의 독립 따옴표 및 백 슬래시는 이스케이프 할 필요는 없지만 사용할 수는 있습니다.

"\"동일합니다.

\\\동일합니다.

의도가 \\를 찾으려면 적어도 선행 백 슬래시를 이스케이프해야합니다. 모두 \\\\\\\작동합니다.

의도 "\ 찾을 경우, 적어도 선두 백 슬래시 이스케이프해야합니다. 모두 \\"\\\"일을.

/ G : FILE 정규식 검색 문자열 내 이스케이프 따옴표 및 백 슬래시
이스케이프 시퀀스는 설명서에 따라 예상대로 작동하는 경우입니다. 인용 부호는 정규식 메타 문자가 아니므로 이스케이프 할 필요는 없습니다 (그러나 가능할 수는 있음). 백 슬래시는 정규식 메타 문자이므로 이스케이프해야합니다.

명령 행 매개 변수의 문자 한계-확장 ASCII 변환
널 문자 (0x00)는 명령 행의 문자열에 나타날 수 없습니다. 다른 단일 바이트 문자는 문자열 (0x01-0xFF)에 나타날 수 있습니다. 그러나 FINDSTR은 명령 행 매개 변수에서 찾은 많은 확장 ASCII 문자를 다른 문자로 변환합니다. 이것은 두 가지 방식으로 큰 영향을 미칩니다.

1) 많은 확장 ASCII 문자는 명령 행에서 검색 문자열로 사용될 경우 서로 일치하지 않습니다. 이 제한은 리터럴 검색과 정규식 검색에서 동일합니다. 검색 문자열에 확장 ASCII가 포함되어야하는 경우 /G:FILE옵션을 대신 사용해야합니다.

2) 이름에 확장 ASCII 문자가 포함되어 있고 파일 이름이 명령 행에 지정된 경우 FINDSTR이 파일을 찾지 못할 수 있습니다. 검색 할 파일에 이름에 확장 ASCII가 포함 된 경우 /F:FILE옵션을 대신 사용해야합니다.

다음은 FINDSTR이 명령 행 문자열에서 수행하는 확장 ASCII 문자 변환의 전체 목록입니다. 각 문자는 10 진수 바이트 코드 값으로 표시됩니다. 첫 번째 코드는 명령 줄에 제공된 문자를 나타내고 두 번째 코드는 변환 된 문자를 나타냅니다. 참고 –이 목록은 미국 컴퓨터에서 컴파일되었습니다. 다른 언어가이 목록에 어떤 영향을 줄지 모르겠습니다.

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

위 목록에없는> 0 문자는 <CR>및 <를 포함하여 자체로 처리됩니다 LF>. 가장 쉬운 방법은 같은 이상한 문자를 포함 할 수 <CR><LF>환경 변수로를 얻고 명령 행 인수 내에서 지연 확장을 사용하는 것입니다.

/ G : FILE 및 / F : FILE 옵션으로 지정된 파일에서 찾은 문자열의 문자 제한
nul (0x00) 문자는 파일에 나타날 수 있지만 C 문자열 종결 자처럼 작동합니다. 널 문자 뒤의 모든 문자는 마치 다른 행에있는 것처럼 다른 문자열로 처리됩니다.

<CR><LF>문자는 문자열을 종료하고, 문자열에 포함되지 않은 라인 종결로 처리됩니다.

다른 모든 단일 바이트 문자는 문자열 내에 완벽하게 포함됩니다.

유니 코드 파일 검색
FINDSTR은 대부분의 유니 코드 (UTF-16, UTF-16LE, UTF-16BE, UTF-32)를 제대로 검색 할 수 없습니다. 유니 코드는 nul 바이트를 검색 할 수없고 일반적으로 많은 nul 바이트를 포함하기 때문입니다.

그러나 TYPE 명령은 BOM이있는 UTF-16LE을 단일 바이트 문자 세트로 변환하므로 다음과 같은 명령은 BOM이있는 UTF-16LE에서 작동합니다.

type unicode.txt|findstr "search"

활성 코드 페이지에서 지원하지 않는 유니 코드 코드 포인트는 ?문자 로 변환됩니다 .

검색 문자열에 ASCII 만 포함되어 있으면 UTF-8을 검색 할 수 있습니다. 그러나 멀티 바이트 UTF-8 문자의 콘솔 출력은 올바르지 않습니다. 그러나 출력을 파일로 리디렉션하면 결과가 UTF-8로 올바르게 인코딩됩니다. UTF-8 파일에 BOM이 포함되어 있으면 BOM이 첫 번째 행의 일부로 간주되어 행의 시작과 일치하는 검색을 중단 할 수 있습니다.

검색 문자열을 UTF-8 인코딩 검색 파일 (BOM없이)에 넣고 / G 옵션을 사용하면 멀티 바이트 UTF-8 문자를 검색 할 수 있습니다.

줄 끝
FINDSTR은 <LF>마다 줄을 즉시 끊습니다. <CR>의 유무는 줄 바꿈에 영향을 미치지 않습니다.

줄 바꿈 검색 검색
예상대로 .정규식 메타 문자는 <CR> 또는 <LF>와 일치하지 않습니다. 그러나 명령 줄 검색 문자열을 사용하여 줄 바꿈을 검색 할 수 있습니다. <CR> 및 <LF> 문자는 모두 명시 적으로 일치해야합니다. 여러 줄 일치가 발견되면 일치하는 첫 번째 줄만 인쇄됩니다. 그런 다음 FINDSTR은 소스의 두 번째 줄로 두 배로 돌아가서 "앞으로보기"유형 기능의 일종으로 검색을 다시 시작합니다.

TEXT.TXT에 이러한 내용이 있다고 가정합니다 (Unix 또는 Windows 스타일 일 수 있음).

A
A
A
B
A
A

그런 다음이 스크립트

@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

이 결과를 제공합니다

1:A
2:A
5:A

<CR> 또는 <LF>와 일치하는 유일한 방법은 EOL 문자를 포함하는 정규식 문자 클래스 범위 표현식을 사용하는 것이므로 / G : FILE 옵션을 사용하여 줄 바꿈을 검색하는 것은 정확하지 않습니다.

  • [<TAB>-<0x0B>] <LF>와 일치하지만 <TAB> 및 <0x0B> 와도 일치

  • [<0x0C>-!] <CR>과 일치하지만 <0x0C>와!

    참고-위의 문자는 그래픽으로 표현할 수 없기 때문에 정규식 바이트 스트림을 상징적으로 표현한 것입니다.

아래 2 부에서 답변이 계속되었습니다 ...


46
뛰어난 완성도. 인터넷의 모든 답변만이 이와 같았다면.
Mike Viens

1
우리는 위에서 언급 한 Win7 교수형 문제와 관련이있을 수있는 Q141344 및 findstr addpath.bat에서 문제가 발생했습니다 . 관심있는 사람을 위해 대화방을 만들었습니다. chat.stackoverflow.com/rooms/13177/…
matt wilkie

2
편집-XP에서 제어 문자를 점으로 표시하여 설명합니다. 또한 짧은 8.3 파일 이름에서 파생 된 버그 /S/D옵션이 문서화되었습니다 .
dbenham

1
편집-1) / F : FILE로 지정된 파일 내의 파일 이름을 인용해서는 안됩니다. 2) 확장 ASCII 문자의 변환은 명령 행에서 제공 될 때 검색 문자열과 파일 이름 모두에 영향을줍니다.
dbenham

1
편집 - 추가 버그는 단일 문자로 구성되어있는 경우, 파이프로 연결된 입력의 마지막 줄이없이 무시<LF>
dbenham

64

위의 1 부부터 답변이 계속 되었습니다.-30,000 자 답변 제한에 도달했습니다.

제한된 정규 표현식 (regex) 지원
정규 표현식에 대한 FINDSTR 지원은 매우 제한적입니다. HELP 문서에없는 경우 지원되지 않습니다.

그 외에도 지원되는 정규 표현식은 완전히 비표준 방식으로 구현되므로 grep 또는 perl과 같은 결과가 다를 수 있습니다.

정규식 라인 위치 앵커 ^ 및 $
^ 는 입력 스트림의 시작과 <LF> 바로 다음의 위치와 일치합니다. FINDSTR도 <LF> 다음에 줄을 나누므로 "^"의 간단한 정규식은 항상 파일 내의 모든 줄, 심지어 이진 파일과도 일치합니다.

$<CR> 바로 앞의 위치와 일치합니다. 이것은 포함하는 정규식 검색 문자열 $이 Unix 스타일 텍스트 파일 내의 행과 절대 일치하지 않으며 <CR> <LF>의 EOL 표시자가없는 경우 Windows 텍스트 파일의 마지막 행과 일치하지 않습니다.

참고 – 앞에서 설명한 것처럼 FINDSTR로 파이프 및 리디렉션 된 입력 <CR><LF>은 소스에없는 추가 된 것일 수 있습니다 . 분명히 이것은를 사용하는 정규식 검색에 영향을 줄 수 있습니다 $.

전에 문자로 모든 검색 문자열 ^또는 후에는 $항상 일치하는 항목을 찾을 수 없게됩니다.

위치 옵션 / B / E / X
위치 적 옵션과 동일하게 작동 ^하고 $문자 검색 문자열에 대한 그들은 또한 일을 제외하고.

/ B ^는 정규식 검색 문자열을 시작할 때와 동일하게 작동 합니다.

/ E $는 정규식 검색 문자열 끝에서 와 동일하게 작동 합니다.

/ X 는 정규식 검색 문자열 ^의 시작과 $끝에 모두있는 것과 동일하게 작동 합니다.

정규식 단어 경계
\<정규식의 첫 번째 용어 여야합니다. 다른 문자가 앞에 오면 정규 표현식과 일치하지 않습니다. \<입력의 맨 처음, 줄의 시작 (<LF> 바로 다음 위치) 또는 "단어가 아닌"문자 바로 다음 위치에 해당합니다. 다음 문자는 "단어"문자 일 필요는 없습니다.

\>정규식의 마지막 용어 여야합니다. 다른 문자가 뒤에 오는 경우 정규 표현식은 아무것도 일치하지 않습니다. \>입력의 끝, <CR> 바로 앞의 위치 또는 "단어가 아닌"문자 바로 앞의 위치에 해당합니다. 앞의 문자는 "단어"문자 일 필요는 없습니다.

다음은 십진 바이트 코드로 표시되는 "단어가 아닌"문자의 전체 목록입니다. 참고 –이 목록은 미국 컴퓨터에서 컴파일되었습니다. 다른 언어가이 목록에 어떤 영향을 줄지 모르겠습니다.

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

정규식 문자 클래스 범위 [xy]
문자 클래스 범위가 예상대로 작동하지 않습니다. 이 질문을보십시오 : 왜 findstr이 대소 문자를 올바르게 처리하지 못합니까 (일부 상황에서)? 이 대답과 함께 : https://stackoverflow.com/a/8767815/1012053 .

문제는 FINDSTR이 바이트 코드 값으로 문자를 대조하지 않는다는 것입니다 (일반적으로 ASCII 코드로 생각되지만 ASCII는 0x00-0x7F로만 정의 됨). 대부분의 정규식 구현은 [AZ]를 모두 대문자 영어 대문자로 취급합니다. 그러나 FINDSTR은 SORT의 작동 방식과 대략 일치하는 데이터 정렬 시퀀스를 사용합니다. 따라서 [AZ]에는 대문자와 소문자 ( "a"제외) 및 발음 구별 부호가있는 영어 이외의 영문자가 모두 포함 된 완전한 영어 알파벳이 포함됩니다.

다음은 FINDSTR에서 지원하는 모든 문자의 전체 목록이며, FINDSTR에서 정규식 문자 클래스 범위를 설정하는 데 사용되는 조합 순서로 정렬되어 있습니다. 문자는 10 진수 바이트 코드 값으로 표시됩니다. 코드 페이지 437을 사용하여 문자를 볼 경우 데이터 정렬 시퀀스가 ​​가장 적합하다고 생각합니다. 참고 –이 목록은 미국 컴퓨터에서 컴파일되었습니다. 다른 언어가이 목록에 어떤 영향을 줄지 모르겠습니다.

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

정규식 문자 클래스 용어 제한 및 버그
FINDSTR은 정규식 내에서 최대 15 자 클래스 용어로 제한 될뿐만 아니라 한도를 초과하려는 시도를 제대로 처리하지 못합니다. 16 개 이상의 문자 클래스 용어를 사용하면 "문자열 찾기 (QGREP) 유틸리티에 문제가 발생 해 닫아야합니다. 불편을 끼쳐 죄송합니다." 라는 대화식 Windows 팝업이 나타납니다 . 메시지 텍스트는 Windows 버전에 따라 약간 다릅니다. 실패 할 FINDSTR의 예는 다음과 같습니다.

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]

이 버그는 DosTips 사용자 Judago에 의해보고되었다 여기 . XP, Vista 및 Windows 7에서 확인되었습니다.

바이트 코드 0xFF (10 진수 255)를 포함하면 정규식 검색이 실패하고 무한정 정지 될 수 있습니다. 바이트 코드 0xFF (10 진수 255)
를 포함하는 정규식 검색은 실패합니다. 바이트 코드 0xFF가 직접 포함되거나 문자 클래스 범위 내에 암시 적으로 포함되면 실패합니다. FINDSTR 문자 클래스 범위는 바이트 코드 값을 기반으로 문자를 대조하지 않습니다. 문자 와 문자 <0xFF>사이의 조합 순서에서 문자 가 비교적 일찍 나타납니다 . 따라서 둘 다 포함 하고 실패 하는 모든 문자 클래스 범위 .<space><tab><space><tab>

정확한 동작은 Windows 버전에 따라 약간 변경됩니다. 0xFF가 포함되어 있으면 Windows 7이 무기한 중단됩니다. XP가 멈추지 않지만 항상 일치하는 항목을 찾지 못하고 때때로 "프로세스가 존재하지 않는 파이프에 쓰려고했습니다."라는 오류 메시지가 표시 됩니다.

더 이상 Vista 컴퓨터에 액세스 할 수 없으므로 Vista에서 테스트 할 수 없습니다.

정규식 버그 : 파일 끝 .[^anySet]일치 할 수 있음
정규식 .메타 문자는 이외의 모든 문자와 만 일치해야합니다.<CR> 또는<LF> . 파일의 마지막 줄이 <CR>또는로 끝나지 않으면 파일 끝과 일치시킬 수있는 버그가 있습니다 <LF>. 그러나 .는 빈 파일과 일치하지 않습니다.

예를 들어, "test.txt"라는 파일은 한 줄의 x 종료없이, <CR>또는 <LF>다음과 일치합니다 :

findstr /r x......... test.txt

이 버그는 XP 및 Win7에서 확인되었습니다.

음수 문자 집합의 경우에도 마찬가지입니다. [^abc]파일 끝 과 같은 것이 있습니다. 긍정적 인 문자 세트는 [abc]정상적으로 작동하는 것 같습니다. Win7에서만 이것을 테스트했습니다.


1
findstr은 또한 큰 파일을 다루는 버그입니다. 2GB보다 큰 파일은 findstr을 정지시킬 수 있습니다. 항상 그런 것은 아닙니다. 버그를 확인하면서 2.3GB 인 파일을 검색했습니다. 단일 파일 만 검색하더라도 정지합니다. 해결 방법은의 출력을 type로 파이프하는 것입니다 findstr.
Disillusioned

또한 findstr여러 /c:검색 문자열 을 지원 하는 것으로 명시 적으로 언급 할 가치가 있습니다. 나는 당신의 대답이 이것을 증명한다는 것을 알고 있습니다. 그러나 그것은 문서화되지 않은 것입니다. findstr몇 년 동안 사용 하지 않은 후에이 기능에 대해 알게되어 매우 놀랐습니다 .
Disillusioned

@CraigYoung-당신은 검색 문자열 소스에 대한 권리입니다. 답변을 편집했습니다. 감사합니다.
dbenham

1
추가 조사에서 LF문서화 한 문제 에 대한 변형으로 보입니다 . 추가 모드 에서 파일을 만들었 LF기 때문에 테스트 파일이 끝나지 않는다는 것을 알았 copy습니다. 문제를 답변하기 위해 명령 줄 세션을 넣었습니다 ( stackoverflow.com/a/22943056/224704 ). 입력은 리디렉션 되지 않지만 검색이 중단됩니다. 정확히 같은 검색 명령 은으로 끝나지 않는 더 작은 파일로 중단되지 않습니다LF .
환멸

1
새로운 발견 (Win7) : 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 문자 클래스)- ErrorLevel = -1073740791 (0xC0000409), 오류 대화창 : Find String (QGREP) Utility has stopped working; 하나의 클래스 또는 두 개의 메타 문자 ( *\.)를 제거한 후 작동합니다.
aschipfl

7

findstr 큰 파일을 검색 할 때 가끔 예기치 않게 정지됩니다.

정확한 조건이나 경계 크기를 확인하지 않았습니다. 2GB보다 큰 파일은 위험 할 수 있습니다.

나는 이것과 혼합 된 경험을 가지고 있었기 때문에 파일 크기 이상입니다. 이 같은이 외모에 변화 될 수있다 입력 LF로 끝나지 않는 리디렉션 경우 XP 및 Windows 7에 FINDSTR 중단 하지만,이 특별한 문제 매니페스트을 보여로 입력되는 경우 하지 리디렉션.

다음 명령 행 세션 (Windows 7) findstr은 3GB 파일을 검색 할 때 정지되는 방법 을 보여줍니다 .

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>

16 진수 편집기에서 모든 줄이로 끝나는 것을 확인했습니다 CRLF. 유일한 예외는 파일이 다음과 같이 종료된다는 것입니다.0x1A 작동 방식copy 으로 인해 입니다. 그러나이 예외 는 "작은"파일에서 문제를 일으키지 않습니다 .

추가 테스트를 통해 다음을 확인했습니다.

  • 이진 파일에 copy대한 /b옵션 과 함께 사용 하면 0x1A문자 가 추가 findstr되지 않으며 3GB 파일에 매달리지 않습니다.
  • 다른 문자로 3GB 파일을 종료하면 a findstr가 중단됩니다.
  • 그만큼 0x1A문자는 "작은"파일에 문제가 발생하지 않습니다. (다른 종료 문자와 유사합니다.)
  • CRLF이후에 추가0x1A 하면 문제가 해결됩니다. ( LF그 자체만으로도 충분할 것입니다.)
  • 중단없이 type파일을 파이프로 파이프 findstr작업에 사용 합니다 . (이것은 부작용 중 하나 일 수 있습니다.type 거나 |추가 라인 끝을 삽입하는 .)
  • 리디렉션 된 입력을 사용 <하면 findstr정지됩니다. 그러나 이것은 예상됩니다. dbenham의 게시물에 설명 된 대로 : "리디렉션 된 입력은 반드시 끝나야합니다 LF" .

1
+1, Win7 컴퓨터에서 문제를 확인할 수 있습니다. 마지막 문자가 아닌 경우 크기가 정확히 2GiB 인 파일이 정지되었습니다 <LF>. 2 바이트 작은 파일이 중단되지 않았습니다. 매우 불쾌합니다!
dbenham

6

여러 명령이 괄호로 묶여 있고 전체 블록으로 경로 재 지정된 파일이있는 경우 :

< input.txt (
   command1
   command2
   . . .
) > output.txt

... 그러면 블록의 명령이 활성화되어있는 동안 파일이 열린 상태로 유지되므로 명령이 경로 재 지정된 파일의 파일 포인터를 이동할 수 있습니다. MORE 및 FIND 명령은 처리하기 전에 Stdin 파일 포인터를 파일의 시작 부분으로 이동하므로 동일한 파일이 블록 내에서 여러 번 처리 될 수 있습니다. 예를 들어이 코드는 다음과 같습니다.

more < input.txt >  output.txt
more < input.txt >> output.txt

...이 것과 동일한 결과를 생성합니다.

< input.txt (
   more
   more
) > output.txt

이 코드는 :

find    "search string" < input.txt > matchedLines.txt
find /V "search string" < input.txt > unmatchedLines.txt

...이 것과 동일한 결과를 생성합니다.

< input.txt (
   find    "search string" > matchedLines.txt
   find /V "search string" > unmatchedLines.txt
)

FINDSTR은 다릅니다. Stdin 파일 포인터를 현재 위치에서 이동 하지 않습니다 . 예를 들어이 코드는 검색 줄 뒤에 새 줄을 삽입합니다.

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

이 예제 와 같이 경로 재 지정된 파일의 파일 포인터를 이동할 수있는 보조 프로그램을 통해이 기능을 잘 활용할 수 있습니다 .

이 동작은 이 게시물 에서 jeb 에 의해 처음보고되었습니다 .


2018-08-18 편집 : 새로운 FINDSTR 버그 가보고되었습니다.

FINDSTR 명령에는이 명령을 사용하여 문자를 컬러로 표시하고 이러한 명령의 출력이 CON 장치로 리디렉션 될 때 발생하는 이상한 버그가 있습니다. FINDSTR 명령을 사용하여 텍스트를 컬러로 표시하는 방법에 대한 자세한 내용은 이 주제를 참조하십시오 .

이 형식의 FINDSTR 명령의 출력이 CON으로 리디렉션되면 텍스트가 원하는 색상으로 출력 된 후 이상한 일이 발생합니다. 텍스트를 "보이지 않는"문자로 출력 한 후의 모든 텍스트 (텍스트는 검정 배경 위에 검정 텍스트로 출력합니다. COLOR 명령을 사용하여 전체 화면의 전경색과 배경색을 재설정하면 원본 텍스트가 나타납니다. 그러나 텍스트가 "보이지 않는"경우 SET / P 명령을 실행할 수 있으므로 입력 한 모든 문자가 화면에 나타나지 않습니다. 이 동작은 암호를 입력하는 데 사용될 수 있습니다.

@echo off
setlocal

set /P "=_" < NUL > "Enter password"
findstr /A:1E /V "^$" "Enter password" NUL > CON
del "Enter password"
set /P "password="
cls
color 07
echo The password read is: "%password%"

2

파일 이름에 en dash (–) 또는 em dash (—)를 사용할 때 첫 번째 답변에서 검색 할 데이터 소스 섹션에 관한 버그를보고하고 싶습니다 .

보다 구체적으로, arguments로 지정된 첫 번째 옵션 인 filenames 을 사용하려고 하면 파일을 찾을 수 없습니다. 재 지정을 통한 옵션 2- stdin 또는 파이프의 3 데이터 스트림을 사용하면 findstr이 파일을 찾습니다.

예를 들어,이 간단한 배치 스크립트는 다음과 같습니다.

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

인쇄합니다 :

en 대시가있는 파일 이름 :

  1. 인수
    FINDSTR로 :-dash.txt로 파일 이름을 열 수 없습니다

  2. 리디렉션을 통한 stdin으로
    나는 대시가있는 파일입니다.

  3. 파이프의 데이터 스트림으로
    나는 대시가있는 파일입니다.

em 대시가있는 파일 이름 :

  1. 인수
    FINDSTR로 :-dash.txt로 파일 이름을 열 수 없습니다

  2. 리디렉션을 통한 stdin으로
    나는 em 대시가있는 파일입니다.

  3. 파이프의 데이터 스트림으로
    em 대시가있는 파일입니다.

도움이 되길 바랍니다.

미디엄.


1
안녕하세요 matro, 귀하의 의견이 정확할 수도 있지만 실제 질문에 대한 답변이 아닌지 잘 모르겠습니다.
Wai Ha Lee

FINDSTR이 지원하지 않는 유니 코드 문제라고 생각합니다. CMD.EXE 리디렉션은 TYPE 명령과 마찬가지로 유니 코드로 파일 이름을 올바르게 열 수 있습니다. 그러나 라인 어딘가에서 FINDSTR은 en-dash와 em-dash를 일반 대시로 변환하며 물론 OS는 해당 이름을 찾을 수 없습니다. en-dash 및 / 또는 em-dash를 대시로 대체하는 다른 파일을 작성하면 FINDSTR은 en-dash 또는 em-dash를 포함하는 이름이 제공된 경우 대시 파일을 검색합니다.
dbenham

이 문제를 버그가 아니라 제한으로 분류하겠습니다.
dbenham

실제로 이것은 ASCII로 확장되므로 유니 코드 문제는 아닙니다. 명령 줄 매개 변수에 대한 문자 제한-확장 ASCII 변환 이라는 제목 아래의 원래 답변에서 이미이 문제를 설명했습니다 . FINDSTR은 다수의 확장 ASCII 코드를 en-dash 및 em-dash를 포함하여 "관련된"true ASCII로 변환합니다.
dbenham

1

findstr명령 세트 ErrorLevel(또는 종료 코드)를 전혀 유효하지 않거나 호환되지 않는 스위치와 더 검색 문자열이 적용 길이 제한을 초과하지가 없음을 주어 다음 값 중 하나에 :

  • 0 지정된 모든 파일에서 최소한 한 줄만 일치하는 경우
  • 1 그렇지 않으면;

다음과 같은 경우 줄이 일치하는 것으로 간주됩니다.

  • /V옵션이 제공 되지 않으며 검색 표현식이 최소한 한 번 발생합니다.
  • /V옵션이 제공되며, 검색 식가 발생하지 않습니다;

즉,이 /V옵션도 반환 된 값을 변경 ErrorLevel하지만 되돌릴 수 는 없습니다 .

예를 들어, 파일을 가지고 할 때 test.txt문자열을 포함 하나가 두 줄, 함께 text하지만, 다른 하나는하지 않는, 모두 findstr "text" "test.txt"findstr /V "text" "test.txt"반환 ErrorLevel의를 0.

기본적으로 다음과 같이 말할 수 있습니다. findstr적어도 한 줄을 반환 하면 로 ErrorLevel설정되고 0그렇지 않으면로 설정 됩니다 1.

/M옵션은 ErrorLevel값에 영향을 미치지 않으며 출력 만 변경합니다.

(완전성을 위해 find명령/V옵션과 관련하여 정확히 동일한 방식으로 작동 ErrorLevel하며 /C옵션은 영향을 미치지 않습니다 ErrorLevel.)


1

FINDSTR에는 내가 설명하고 해결 한 색상 버그가 있습니다. /superuser/1535810/is-there-a-better-way-to-mitigate-this-obscure-color-bug-when-piping-to 있습니다. -findstr / 1538802? noredirect = 1 # comment2339443_1538802

이 스레드를 요약하면 버그는 괄호로 묶은 코드 블록 내에서 입력을 FINDSTR로 파이프하면 인라인 ANSI 이스케이프 색상 코드가 나중에 실행되는 명령에서 작동하지 않는다는 것입니다. 인라인 색상 코드의 예는 다음과 같습니다.echo %magenta%Alert: Something bad happened%yellow% 색상 과 (여기서 마젠타 및 노랑은 .bat 파일에서 해당 ANSI 이스케이프 색상 정의 된 변수입니다).

나의 초기 해결책은 FINDSTR 이후에 할 일 없음 서브 루틴을 호출하는 것이 었습니다. 어떻게 든 호출이나 반환은 재설정해야 할 모든 것을 "재설정"합니다.

나중에 다음과 같이 더 효율적인 다른 솔루션을 발견했습니다. 다음 예와 같이 FINDSTR 구문을 괄호 안에 echo success | ( FINDSTR /R success ) 넣으십시오. FINDSTR 구문을 중첩 된 코드 블록 안에 배치하면 FINDSTR의 색상 코드 버그가 분리되어 중첩 된 외부의 내용에 영향을 미치지 않습니다. 블록. 아마도이 기술은 원치 않는 다른 FINDSTR 부작용을 해결할 것 입니다.


좋은 발견. 그러나 규칙을 단순화 할 수 있습니다 (적어도 엔터프라이즈 Windows 10 시스템에서는). FINDSTR은 모든 콘솔 이스케이프 시퀀스가 ​​동일한 명령 블록 내에서 후속 명령에 대해 작동하지 못하게합니다. FINDSTR이 파이프, 리디렉션 된 입력 또는 파일을 읽는지 여부는 중요하지 않습니다. 이스케이프 시퀀스 실패는 색상 코드로 제한되지 않습니다. 명령 블록은 괄호 안의 명령 집합 및 / 또는 &, && 또는 ||를 통해 연결된 명령입니다.
dbenham

@ dbenham : 문제의 좋은 일반화. 괄호 안에 FINDSTR 문구를 중첩하여 내 솔루션이 일반적인 경우에도 작동하는지 알고 있습니까? 그리고 내 솔루션에 바람직하지 않은 부작용이 있는지 알고 있습니까?
돌로레스 스티븐스

철저한 테스트를 수행하지는 않았지만 중첩 된 괄호는 일반적인 해결책 인 것 같으며 바람직하지 않은 부작용을 생각할 수 없습니다.
dbenham

-1

여러 디렉토리에 대한 / D 팁 : 검색 문자열 앞에 디렉토리 목록을 넣으십시오. 이것들은 모두 작동합니다 :

findstr /D:dir1;dir2 "searchString" *.*
findstr /D:"dir1;dir2" "searchString" *.*
findstr /D:"\path\dir1\;\path\dir2\" "searchString" *.*

예상대로 경로를로 시작하지 않으면 경로는 위치를 기준으로합니다 \. "디렉토리 이름에 공백이없는 경우 경로를 둘러싸는 것은 선택 사항입니다. 결말 \은 선택 사항입니다. 위치 출력에는 사용자가 제공 한 경로가 포함됩니다. 디렉토리 목록을 포함하거나 포함하지 않고 작동합니다 ".


여기에 문서화되지 않은 내용이 없습니다. / D 옵션은 내장 도움말에 설명되어 있습니다. FINDSTR 사용 방법에 대한 일반적인 팁은 문제가되지 않습니다. 문서화되지 않은 기능, 제한 사항 및 / 또는 버그를 나열하기위한 것입니다.
dbenham

1
@ dbenham 사실 그것이 문서화되지 않은 것은 아니지만, 내가 원하는 결과를 얻기 위해 findstr과 함께해야한다는 것을 알았고 DID가 작동하는 것을 공유하고 사람들은 작동하지 않는 명령으로 실험하는 데 시간을 낭비하지 않았습니다. hth (나는 당신이 나의 입력을 싫어한다는 것이 슬프다 – 단지 건설적인 의도였다)
gordon

IMHO / D 스위치는 내장 도움말에 명확하게 설명되어 있으며 /D:dirlist Search a semicolon-delimited list of directories검색 문자열 앞에 위치하므로 / D 스위치에 대해 "발견 된"항목과 "명령어"가 무엇인지 이해하지 못합니다. 작동하지 않습니다 ") ...
Aacini

@Aacini는 많은 언어에서 속성의 순서는 중요하지 않습니다. findstr목록 / D에 대한 설명서를 먼저 이해합니다 . 예, 문서화 된 기능에 대한 논쟁은 없습니다. 속성의 순서가 중요하다는 문제에 대해서는 문서화되어 있지 않습니다. 나는 명령 줄 작업을 거의하지 않으므로 명령을 결합 할 때 순서가 차이를 알지 못했을 때 속성에 추가 할 때 속성을 추가하는 것만 큼 알파벳순으로 C가 D보다 우선합니다. 나는 정말 좌절해서 커맨드 라인을 많이 사용하지 않는 다른 사람들을 위해 "발견 된"경험을 공유했습니다.
gordon

1
의 순서 선택적 속성 일반적으로 중요하지 않습니다. findstr내용은 해당 지정 strings부분이 NOT 선택하고 이후에 배치해야 선택 속성과 전에 옵션 파일 이름 목록입니다. "찾은 파일"이 사용 형식을 따르지 않고 명령을 사용하면 오류가 발생하는 경우 해당 요점이 잘 문서화되어 있습니다. 참조 명령 구문 : "구문은 명령과 그 뒤에 이어지는 매개 변수를 입력해야하는 순서에 나타납니다"
Aacini
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.