Linux에서 grep을 사용하여 CRLF (dos line endings)를 포함하는 파일을 어떻게 검색합니까?


126

Linux에서 grep으로 끝나는 dos 줄이 포함 된 파일을 검색하고 싶습니다. 이 같은:

grep -IUr --color '\r\n' .

위의 rn내용은 원하는 것이 아닌 리터럴과 일치하는 것 같습니다 .

이것의 출력은 xargs를 통해 todos로 파이프되어 crlf를 lf로 변환합니다.

grep -IUrl --color '^M' . | xargs -ifile fromdos 'file'

2
dos2unix 를 사용해 보셨습니까 ? 줄 끝을 자동으로 수정합니다.
sblundy

확실하지는 않지만 '와'안에 패턴을 인용하는 것에는 차이가 있습니다. '로 묶인 패턴의 Afaik은 이스케이프 시퀀스가 ​​적절한 문자열로 해석되므로'\ r '은 "\\ r"및 "와 동일합니다. \ r "에는 '와 동등한 (적어도 해당 표기법에서)이 없습니다.
Anticom

Anticom :이 경우 '와'의 차이는 관련이 없다는 것이 맞습니다. 그러나 일반적으로 '둘러싸여있는 문자열은 약하게 인용되고 "는 강한 인용으로 구분됩니다. 내가 활용하는 가장 큰 장점은 $ 확장 또는``약한 인용 문자열로 확장하지 않는다는 것입니다. 자세한 내용 은 인용에 대한 bash-hackers를 참조하십시오 .
bschlueter

4
가장 쉬운 방법은 스위치 dos2unix와 함께 현대식을 사용하는 것입니다 -ic. LF 파일의 경우 unix2dos로 검색 할 수 있습니다 -ic. 파일을 수정하지 않습니다. 보고 만하십시오.
gavenkoa

3
이것은 Linux에서 Windows 라인 엔딩 / 캐리지 리턴과 관련된 모든 질문에 대한 최고의 답변이기 때문에 명령을 사용하여 터미널에서 수 있다는 점에 주목할 가치가 있다고 생각합니다 cat -v somefile.txt. 그들은으로 표시^M
user5359531

답변:


121

Ctrl+ V, Ctrl+ M를 사용 하여 grep 문자열에 리터럴 캐리지 리턴 문자를 입력합니다. 그래서:

grep -IUr --color "^M"

^M내가 제안한대로 입력 한 리터럴 CR이 있으면 작동 합니다.

파일 목록을 원하면 -l옵션도 추가해야합니다 .

설명

  • -I 바이너리 파일 무시
  • -Ugrep이 CR 문자를 제거하는 것을 방지합니다. 기본적으로 텍스트 파일이라고 판단되면 수행합니다.
  • -r 각 디렉토리 아래의 모든 파일을 재귀 적으로 읽습니다.

3
빠른 해킹으로 작동하지만 인간 readbale 솔루션은 다음과 같습니다. grep $ '\ r'/ bash shell only / or grepprintf '\r'
akostadinov

5
@akostadinov +1, 그러나 백틱이 귀하의 의견에서 해석되었습니다.) 두 번째 옵션은 즉, grep $(printf '\r'). 그러나 bash와 관련된 대부분의 실제 사용에는 $'\r'.
jankes

3
참고 :이 옵션 -U은 Windows (또는 cygwin)에만 관련이 있지만 여기에서 중요합니다. Windows에서는 명령이 없으면 작동하지 않습니다.
sleske

3
옵션의 포인트는 무엇입니까 -I? 매뉴얼에 따르면 바이너리 파일은 일치하지 않는 것으로 간주됩니다. -I-U(바이너리 유형을 적용 하는) 조합으로 인해 모든 파일이 일치하지 않는 것으로 간주되지 않습니까?
Jānis Elmeris 2013

3
추가 옵션으로 '-l'플래그를 언급했지만 질문은 본질적으로 파일 목록을 요구하기 때문에 기본 답변에 포함되어야한다고 생각합니다. 또한 검색 속도가 빨라집니다.
arr_sea

168

grep은 아마도 당신이 원하는 도구가 아닐 것입니다. 모든 파일에서 일치하는 모든 줄에 대해 한 줄을 인쇄합니다. 10 줄 파일에서 todos를 10 번 실행하고 싶지 않다면 grep은 최선의 방법이 아닙니다. find를 사용하여 트리의 모든 파일에서 파일을 실행 한 다음 "CRLF"에 대한 파일을 검색하면 dos 스타일 줄 끝이있는 각 파일에 대해 한 줄의 출력을 얻을 수 있습니다.

find . -not -type d -exec file "{}" ";" | grep CRLF

다음과 같은 것을 얻을 것입니다.

./1/dos1.txt: ASCII text, with CRLF line terminators
./2/dos2.txt: ASCII text, with CRLF line terminators
./dos.txt: ASCII text, with CRLF line terminators

나는 이미 이것을 깨뜨 렸지만 어쨌든 감사합니다. grep -IUrl --color '^M' . | xargs -ifile fromdos 'file'
Tim Abell

5
grep의 -l 옵션은 각 파일의 일치 항목을 나열하는 대신 파일을 한 번만 나열하도록 지시합니다.
pjz

8
file프로그램의 (문서화되지 않은, 인간 소비 지향적 인) 행동에 의존하는 좋은 해결책이 아닙니다 . 이것은 매우 취약합니다. (하나만) 예 : XML 파일에서 작동하지 않으며 줄 바꿈 유형에 관계없이 file보고서를 작성 XML document text합니다.
leonbloy

1
@leonbloy, 옵션은 -m /dev/nullfind (GNU findutils) 4.4.2(Ubuntu 12.04) 에서 소문자로 보입니다 .
EarlCrapstone

8
이 답변이 가장 마음에 듭니다. 단순히 한find . -type f | xargs file | grep CRLF
brianz

58
grep -IUlr $'\r'

explainshell.com-grep -IUlr


11
감사! 뒤 따르는 사람들을 명확하게하기 위해 bash 매뉴얼은 "$ 'string'형식의 단어는 특별히 취급됩니다. 단어는 문자열로 확장되며 ANSI C 표준에 지정된대로 백 슬래시 이스케이프 문자가 대체됩니다." (이 참조 지원 코드 목록 )
숀 Gugler에게

5
그래서 이것은 bash 특정입니까? 그렇다면 주목해야합니다.
cubuspl42

autocrlf가 좋지 않은 자식의 경우 다음을 사용합니다. grep -IUlrZ $ '\ r'| xargs를 -0 나오지 -zbi의 / \ 연구 // g '
buzard

16

grep 버전이 -P (-perl-regexp) 옵션을 지원하는 경우

grep -lUP '\r$'

사용 될수있다.


8
# list files containing dos line endings (CRLF)

cr="$(printf "\r")"    # alternative to ctrl-V ctrl-M

grep -Ilsr "${cr}$" . 

grep -Ilsr $'\r$' .   # yet another & even shorter alternative

3

쿼리는 검색이었습니다 ... 비슷한 문제가 있습니다 ... 누군가 버전 제어에 혼합 줄 끝을 제출 했으므로 이제 0x0d 0x0d 0x0a줄 끝 이있는 파일이 많이 있습니다. 참고

grep -P '\x0d\x0a'

모든 줄을 찾는 반면

grep -P '\x0d\x0d\x0a'

grep -P '\x0d\x0d'

줄을 찾지 못하므로 줄 끝 패턴과 관련하여 grep 내부에서 "다른"작업이 진행될 수 있습니다.


3

유닉스에서 파일 명령을 사용할 수 있습니다. 줄 종결 자와 함께 파일의 문자 인코딩을 제공합니다.

$ file myfile
myfile: ISO-8859 text, with CRLF line terminators
$ file myfile | grep -ow CRLF
CRLF  

1

나처럼 미니멀리스트 유닉스에 파일 명령 과 같은 기능이 포함되어 있지 않고 grep 표현식의 백 슬래시가 협조하지 않으면 다음을 시도하십시오.

$ for file in `find . -type f` ; do
> dump $file | cut -c9-50 | egrep -m1 -q ' 0d| 0d'
> if [ $? -eq 0 ] ; then echo $file ; fi
> done

위의 수정 사항은 다음과 같습니다.

  • 검색 할 파일 만 찾기 위해 find 명령을 조정하십시오.
  • dump 명령을 od 또는 가지고있는 파일 덤프 유틸리티로 변경하십시오.
  • cut 명령에 선행 및 후행 공백과 덤프 유틸리티 의 16 진 문자 출력 만 포함되어 있는지 확인합니다.
  • 효율성을 위해 덤프 출력을 처음 1000 자로 제한하십시오.

예를 들어, dump 대신 od 를 사용하면 다음과 같이 작동 할 수 있습니다 .

 od -t x2 -N 1000 $file | cut -c8- | egrep -m1 -q ' 0d| 0d|0d$'

1

dos2unix 변환 될 파일을 표시하는 데 사용할 수있는 파일 정보 옵션이 있습니다.

dos2unix -ic /path/to/file

재귀 적으로 수행하려면 bashglobstar옵션을 사용할 수 있습니다.이 옵션은 현재 쉘에 대해 다음과 shopt -s globstar같이 활성화됩니다 .

dos2unix -ic **      # all files recursively
dos2unix -ic **/file # files called “file” recursively

또는 다음을 사용할 수 있습니다 find.

find -exec dos2unix -ic {} +            # all files recursively
find -name file -exec dos2unix -ic {} + # files called “file” recursively
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.