주석을 무시하고 파일을 어떻게 구별합니까? (#로 시작하는 줄)?


55

패키지 관리자의 원본과 직접 수정 한 두 가지 구성 파일이 있습니다. 나는 행동을 설명하기 위해 몇 가지 의견을 추가했습니다.

diff주석을 건너 뛰고 구성 파일에서 어떻게 실행할 수 있습니까? 주석 처리 된 행은 다음에 의해 정의됩니다.

  • 선택적 선행 공백 (탭 및 공백)
  • 해시 기호 ( #)
  • 다른 캐릭터

첫 번째 요구 사항을 건너 뛰는 가장 간단한 정규식은입니다 #.*. GNU diff 3.0 의 --ignore-matching-lines=RE( -I RE) 옵션을 시도했지만 해당 RE와 함께 작동하지 못했습니다. 또한 노력 .*#.*.*\#.*운이없이. 문자 ( Port 631)를 문자 RE와 일치시키지 않고 슬래시 사이에 RE를 두는 것도 도움이되지 않습니다.

“diff”툴에서 제안한 것처럼 정규 표현식의 맛이 부족한 것 같습니까? , 나는 시도했다 grep -G:

grep -G '#.*' file

이것은 의견과 일치하는 것 같지만 작동하지 않습니다 diff -I '#.*' file1 file2.

그렇다면이 옵션을 어떻게 사용해야합니까? diff특정 줄 을 건너 뛰 려면 어떻게해야합니까 (내 경우에는 주석)? grep파일을 제안 하고 임시 파일을 비교 하지 마십시오 .


12
-I옵션을 사용하면 모든 행이 정규 표현식과 일치하는 경우에만 블록이 무시됩니다 . 따라서 주석 전용 변경은 무시할 수 있지만 주석이 아닌 변경에 가까운 주석 변경은 무시할 수 있습니다.
Gilles

@Gilles : 감사합니다. 이제 diff -I예상대로 동작하지 않는 이유를 알 수 있습니다 . 나는이 행동을 분명히하는 예제로 내 대답을 업데이트했습니다.
Lekensteyn

답변:


49

Gilles에 따르면,이 -I옵션 내에서 일치하는 것을 제외하고 일치하는 항목이 없으면 옵션은 한 줄만 무시합니다 -I. 테스트하기 전까지는 완전히 얻지 못했습니다.

시험

내 테스트에는 세 가지 파일이 포함되어 있습니다.
File test1:

    text

파일 test2:

    text
    #comment

파일 test3:

    changed text
    #comment

명령 :

$ # comparing files with comment-only changes
$ diff -u -I '#.*' test{1,2}
$ # comparing files with both comment and regular changes
$ diff -u -I '#.*' test{2,3}
--- test2       2011-07-20 16:38:59.717701430 +0200
+++ test3       2011-07-20 16:39:10.187701435 +0200
@@ -1,2 +1,2 @@
-text
+changed text
 #comment

다른 방법

-I옵션을 올바르게 사용하는 방법을 지금까지 설명하는 대답이 없으므로 bash 쉘에서 작동하는 대안을 제공합니다.

diff -u -B <(grep -vE '^\s*(#|$)' test1)  <(grep -vE '^\s*(#|$)' test2)
  • diff -u -통일 차이
    • -B -빈 줄 무시
  • <(command)- 프로세스 대체 라는 bash 기능으로 명령에 대한 파일 디스크립터가 열리므로 임시 파일이 필요하지 않습니다.
  • grep -패턴과 일치하는 라인을 인쇄하기위한 명령
    • -v -일치하지 않는 줄 표시
    • E -확장 정규식 사용
    • '^\s*(#|$)' -주석과 빈 줄과 일치하는 정규 표현식
      • ^ -줄의 시작과 일치
      • \s* -공백 (탭과 공백)이 있으면 일치
      • (#|$) 해시 마크 또는 라인의 끝과 일치

6

시험:

diff -b -I '^#' -I '^ #' file1 file2

정규 표현식은 두 파일의 해당 줄과 일치해야하며 작동하기 위해 덩어리에서 변경된 모든 줄과 일치해야합니다. 그렇지 않으면 여전히 차이가 표시됩니다.

작은 따옴표를 사용하여 셸 확장으로부터 패턴을 보호하고 정규식 예약 문자 (예 : 대괄호)를 이스케이프하십시오.

우리는 diffutils매뉴얼을 읽을 수 있습니다 :

그러나, -I덩어리에서 변경된 모든 행 (모든 삽입 및 모든 삭제)이 정규식과 일치하는 경우 정규식을 포함하는 행의 삽입 또는 삭제 만 무시합니다.

즉, 무시할 수없는 각 변경에 대해 무시할 수 diff있는 변경을 포함하여 근처에있는 변경의 전체 세트를 인쇄합니다. 둘 이상의 -I옵션 을 사용하여 무시할 행에 둘 이상의 정규식을 지정할 수 있습니다 . diff마지막 줄부터 시작하여 각 줄을 각 정규 표현식과 일치시킵니다.

이 행동은 또한 armel 여기에 잘 설명되어 있습니다 .

관련 : 모든 주석을 무시하는 diff를 어떻게 수행 할 수 있습니까?


2

웹을 검색 한 후 Lekensteyn의 대체 방법이 내가 찾은 더 나은 방법입니다.

그러나 dif 출력을 패치로 사용하고 싶습니다. "grep -v"때문에 행 번호가 유지되므로 문제가 있습니다.

그래서 나는이 명령 줄을 개선하려고합니다.

diff -u -B <(sed 's/^[[:blank:]]*#.*$/ /' file1)  <(sed 's/^[[:blank:]]*#.*$/ /' file2)

완벽하지는 않지만 줄 번호는 패치 파일에 유지됩니다.

그러나 주석 줄 대신 새 줄을 추가하면 패치 할 때 주석이 Hunk FAILED를 생성합니다.

File test1:
  text
  #comment
  other text
File test2:
  text
  new line here
  #comment changed
  other text changed

지금 우리의 명령을 테스트

$ echo -e "#!/usr/bin/sed -f\ns/^[[:blank:]]*#.*$/ /" > outcom.sed
$ echo "diff -u -B <(./outcom.sed \$1)  <(./outcom.sed \$2)" > mydiff.sh
$ chmod +x mydiff.sh outcom.sed
$ ./mydiff.sh file1 file2 > file.dif
$ cat file.dif
--- /dev/fd/63  2014-08-23 10:05:08.000000000 +0200
+++ /dev/fd/62  2014-08-23 10:05:08.000000000 +0200
@@ -1,2 +1,3 @@
 text
+new line

-other text
+other text changed

/ dev / fd / 62 & / dev / fd / 63은 프로세스 대체에 의해 생성 된 파일입니다. "+ new line"과 "-other text"사이의 줄은 주석을 대체하기 위해 sed 표현식에 정의 된 기본 공백 문자입니다.

그리고 이제이 패치를 적용 할 때오고있는 것은 :

$ patch -p0 file1 < file.dif 
patching file file1
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file file1.rej

해결책은 -u없이 통합 diff 형식을 사용하지 않는 것입니다

$ echo "diff -B <(./outcom.sed \$1)  <(./outcom.sed \$2)" > mydiff.sh
$ ./mydiff.sh file1 file2 > file.dif
$ cat file.dif
1a2
> new line
3c4
< other text
---
> other text changed
$ patch -p0 file1 < file.dif 
patching file file1
$ cat file1
text
new line
#comment
other text changed

이제 패치 파일 작업 파일 (복잡한 diff 프로세스의 결과에 대한 보증없이).


컨텍스트 차이로 인해 통합 diff가 적용되지 않습니다. diff -U0 one two컨텍스트를 비활성화하는 데 사용할 수 있습니다 . 패치에는 kdiff3와 같이 더 적합한 도구가 많이 있습니다.
Lekensteyn

-U0컨텍스트를 비활성화 하는 옵션에 감사드립니다 . 참고 : kdiff3은 그래픽 도구입니다. git merge 속성을 관리하는 자동 도구가 필요합니다.
syjust

vimdiff3 방향 병합을 지원합니다.
Lekensteyn

더 정확하게 말하자면 SQL 스크립트에서 exludes를 사용하여 git merge 프로세스를 자동화하는 스크립트 도구가 필요합니다. kdiff3 및 vimdiff는 대화식 도구이며 제 경우에는 사용할 수 없습니다.
syjust

1

나는 보통이 방법을 무시한다 :

  • 주석 처리되지 않은 버전을 사용하여 다른 버전을 생성 grep -v "^#" | cat -s하거나
  • vim -d파일을 보는 데 사용 합니다. 구문 강조는 주석과 주석이 아닌 차이점을 매우 명확하게 처리합니다. 인라인 차이의 차이점을 강조 표시하여 어떤 값 또는 값의 일부가 한눈에 변경되었는지 확인할 수 있습니다.

0

다음은 주석 처리 된 행을 제거하는 데 사용하는 것입니다-탭이나 공백으로 시작하는 행과 빈 행을 제거하십시오.

egrep -v "^$|^[[:space:]]*#" /path/to/file

아니면 할 수있다

sed -e '/^#.*/d' -e 's/#.*//g' | cat -s
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.