파일 끝에서 diff가 개행을 검사하지 못하도록 방지


21

비교하고 싶은 두 개의 큰 나무가 있습니다. 트리의 일부 파일은 하나에 줄 바꿈이 있고 다른 파일에는이 줄 바꿈이 없기 때문에 다릅니다. 이 사실을 무시하고 싶습니다. 나는 다음 diff과 같이 전화를 시도했다 .

diff --ignore-all-space -r <dir1> <dir2>

그리고 이것은 효과가 있습니다. 내 문제는 중요 할 수있는 다른 차이 (공간 관련)도 무시한다는 것입니다.

요약 : 나는 단지 EOF에서 줄 바꿈을 무시해야합니다. 이 가능 diff합니까?

답변:


17

기본적으로 후행 바이트를 무시하고 두 파일을 비교해야합니다. 이를위한 'diff'옵션은 없지만 여러 가지 방법이 있습니다 (예를 들어, 16 진 diff도 고려됩니다).

'diff'를 사용하려면 기본적으로 파일 끝에 줄 바꿈이없는 파일을 수정 한 다음 비교해야합니다. 수정 된 파일을 사용하여 임시 디렉토리를 작성하거나 약간의 스크립트를 사용하여 메모리에서 수행 할 수 있습니다. (바람직한 것은 환경 설정, 파일 크기, 파일 수에 따라 다릅니다.)

예를 들어, 다음은 파일 내용 sed -i을 수정하여 (제자리에서 수정하고 stdout으로 인쇄) 줄 바꿈이없는 경우 줄 바꿈을 추가하거나 줄 바꿈이 이미 있으면 파일을 변경하지 않은 채로 둡니다.

sed -e '$a\'  file1.txt

그리고 'diff'구문을 검토하기 만하면 (참을 반환하면 동일하다는 것을, 거짓은 다른 것을 의미합니다)

$ diff a/file1.txt   b/file1.txt  \
      && echo '** are same' || echo '** are different'
2c2
< eof
---
> eof
\ No newline at end of file
** are different

공백 만 다른지 확인하십시오.

$ diff --ignore-all-space  a/file1.txt   b/file1.txt \
     && echo '** are same' || echo '** are different'
** are same

bash에서는 'sed'를 사용하여 파일 내용이 'diff'(원본 파일은 변경되지 않은 상태)로 전달 될 때 파일 내용을 조작 할 수 있습니다.

$ diff <(sed -e '$a\' a/file1.txt) <(sed -e '$a\' b/file1.txt) \
     && echo '** are same' || echo '** are different'
** are same

이제 diff -r디렉토리를 재귀 적으로 비교 하기 위해 에뮬레이션 만하면 됩니다. 만약 디렉토리를 비교 a하고 b모든 파일을 한 후, a(예를 들어, a/dir1/dir2/file.txt에 파일)를 도출 경로 b(예 b/dir1/dir2/file.txt)와 비교 :

$ for f in $( find a -type f  )
> do
>    diff <(sed -e '$a\' $f) <(sed -e '$a\' b/${f#*/})
> done

약간 더 자세한 버전 :

$ for f in $( find a -type f  )
> do
>   f1=$f
>   f2=b/${f#*/}
>   echo "compare: $f1 $f2"
>   diff <(sed -e '$a\' $f1) <(sed -e '$a\' $f2) \
>       && echo '** are same' || echo '** are different'
> done && echo '** all are same' || echo '** all are different'
compare: a/file1.txt b/file1.txt
** are same
compare: a/file2.txt b/file2.txt
** are same
** all are same

sed -e '$a\'정확히 무엇을 설명해 주 시겠습니까? thx
törzsmókus

실행되지 sed다음 (주어진 -e파일 (의 끝을 일치) 스크립트 / 표현 $합니다 (`\`후 아무것도)), 그리고 '추가'액션 (A \)를 수행하지만, 실제로 텍스트를 지정하지 않는 파일 끝에 EOF / 개행을 추가하려고합니다 (없는 경우에만).
마이클

고마워. a\ 아직 보지 못했습니다.
törzsmókus

1

각 파일에 줄 바꿈을 추가하고 diff (옵션 -B) 의 빈 줄을 무시하여 문제를 해결했습니다 . 이 솔루션은 사용 사례에 적합하지 않을 수 있지만 다른 사용자에게 도움이 될 수 있습니다.

echo >> $FILE1 
echo >> $FILE2
diff -B $FILE1 FILE2 

0

보고 싶지 않은 메시지를 삭제 diff하는 grep명령으로 출력을 파이프합니다 .


안좋다. --ignore-all-space를 추가하지 않으면 diff -r이 결과! = 0으로 존재합니다. 분명히하기 위해 : diff가 EOF에서 줄 바꿈을 무시하고 EOF에서만 무시하고 싶습니다. 그리고이 기준과 일치하는 결과를보고하고 싶습니다. 즉, 트리의 파일이 EOF에서 줄 바꿈에서만 다를 경우 차이로 간주해서는
안되므로

0

더 큰 파일에는 효과가 있지만 원본 파일을 복사하거나 수정하지 않는 다른 방법도 생각했습니다. 재귀 디렉토리 탐색을 여전히 에뮬레이션해야하지만 (여러 가지 방법이 있습니다)이 예제는 'sed'를 사용하지 않고 cmp, 예를 들어 다음을 사용하여 마지막 바이트를 제외하고 두 파일을 비교합니다 .

$ cmp  a/file1.txt  b/file1.txt  && echo '** are same' || echo '** are different'
cmp: EOF on b/file1.txt
** are different

$ du -b a/file1.txt  b/file1.txt 
13  a/file1.txt
12  b/file1.txt

$ cmp  -n 12 a/file1.txt  b/file1.txt  && echo '** are same' || echo '** are different'
** are same

여전히 디렉토리의 모든 파일을 반복하고 두 개의 파일 a / file.txt 및 b / file.txt를 반복하여 더 큰 파일 크기를 계산하고 1을 뺀 다음 cmp바이트 수를 사용하여 이진 diff ( )를 수행하십시오. 세게 때리다):

(( bytes = $(du -b a/file.txt  b/file.txt  | sort -nr | head -1  | cut -f1) - 1 ))
cmp -n $bytes a/file.txt b/file.txt

파일을 반복하는 것은 sedand를 사용하는 다른 답변 과 동일 diff합니다.


0

대답은 간단합니다.
누락 된 줄 바꿈에 대한 메시지는 출력 스트림이 diff아니라 오류 스트림에 있습니다. 너바나에게 구부리세요

diff -rqEeB fileA fileB 2> /dev/null

차이점을 발견하고 해당 값을 확인하려면 diff가 값! = 0을 반환합니다. / dev / null로 리디렉션하면 차이점을 잊어 버리지 않으므로 반환되는 값은! = 0이므로 원하지 않습니다. 나는 유일한 차이점은 마지막 개행 경우 DIFF이 두 파일이 동일 고려할
dangonfast

-1

DIFF commnad의 플래그가있다 : --strip-trailing-cr당신이 요청 정확히 무엇을 그


-1. 이것을 시도 했습니까? 그것은 취급 /r/n같이 /n및 추가와는 아무 상관이없는 /n단지 EOF 전합니다.
Kamil Maciorowski

나는 이것을 시도하고 다른 dos / unix 줄 바꿈으로 파일을 비교하는 데 사용했습니다 ... 정확하지 않습니까?
dharman

문제는 EOF (파일 끝)에서만 줄 바꿈을 무시하는 것입니다.
Kamil Maciorowski
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.