주석(#으로 시작하는 줄)을 무시하고 파일을 구별하는 방법은 무엇입니까?

주석(#으로 시작하는 줄)을 무시하고 파일을 구별하는 방법은 무엇입니까?

두 개의 구성 파일이 있습니다. 하나는 패키지 관리자의 원본 구성 파일이고 다른 하나는 제가 직접 수정한 사용자 정의 구성 파일입니다. 동작을 설명하기 위해 몇 가지 설명을 추가했습니다.

diff구성 파일 건너뛰기 주석을 실행하는 방법은 무엇입니까 ? 주석 줄은 다음과 같이 정의됩니다.

  • 선택적 선행 공백(탭 및 공백)
  • 해시태그( #)
  • 다른 문자

첫 번째 요구 사항을 건너뛰는 (가장 간단한) 정규식은 입니다 . GNU diff 3.0의 ( ) 옵션을 #.*시도했지만 해당 RE에서 작동하지 못했습니다. 나도 시도했지만 운 이 없었습니다. 문자 그대로, 라인( )을 아무것도 일치하지 않는 것으로 두고 슬래시 사이에 RE를 넣는 것도 도움이 되지 않습니다.--ignore-matching-lines=RE-I RE.*#.*.*\#.*Port 631RE

제안대로"diff" 도구의 정규식 스타일이 부족한 것 같나요?, 나는 다음을 시도했습니다 grep -G.

grep -G '#.*' file

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

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

답변1

Gilles에 따르면 -I이 옵션은 세트에서 를 제외하고 일치하는 항목이 없는 경우에만 행을 무시합니다 -I. 테스트하기 전까지는 완전히 이해하지 못했습니다.

시험을 치르다

내 테스트에는 세 가지 파일이 포함됩니다
.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*- 공백(탭 및 공백)이 있는 경우 일치합니다.
      • (#|$)해시 태그 또는 줄 끝과 일치합니다.

답변2

노력하다:

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

정규식은 두 파일의 해당 줄과 일치해야 하며, 작동하려면 블록에서 변경된 모든 줄과 일치해야 합니다. 그렇지 않으면 여전히 차이점이 표시됩니다.

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

우리는 읽을 수 있습니다diffutils수동:

그러나 -I블록에서 변경된 모든 줄(모든 삽입 및 모든 삭제)이 정규식과 일치하는 경우 정규식이 포함된 줄의 삽입 또는 삭제만 무시됩니다.

즉, 무시할 수 없는 각 변경 사항에 대해 diff무시할 수 있는 변경 사항을 포함하여 주변에 있는 전체 변경 사항 집합을 인쇄합니다. 여러 -I옵션을 사용하여 무시할 줄에 대해 여러 정규식을 지정할 수 있습니다. diff주어진 마지막 줄부터 시작하여 각 줄을 각 정규식과 일치시켜 보세요.

이 동작도 잘 설명되어 있습니다.아메르가 여기 있어요.

관련된:모든 주석을 무시하는 diff를 수행하는 방법은 무엇입니까?

답변3

인터넷으로 검색해보니 Lekenstein과 비슷한 방법을 찾았습니다.

diff그런데 출력을 입력으로 사용 patch하고 형식을 변경하고 싶어서 grep -v할 수 없습니다.

어쩌면 이것이 개선된 것일 수도 있습니다.

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

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

그러나 주석 줄 대신 새 줄을 추가하면 주석으로 인해 패치가 실패하게 됩니다.

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

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

$ 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

이제 패치 파일이 작동합니다(그러나 더 복잡한 경우는 보장되지 않습니다).

답변4

모든 주석 줄(탭이나 공백으로 시작하는 줄 포함)과 빈 줄을 제거하는 데 사용하는 방법은 다음과 같습니다.

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

아니면 당신이 할 수 있습니다

sed -e '/^#.*/d' -e 's/#.*//g' | cat -s

관련 정보