이스케이프된 해시 문자가 포함된 파일에서 모든 주석을 제거하는 방법

이스케이프된 해시 문자가 포함된 파일에서 모든 주석을 제거하는 방법

이 질문이 이전에 요청된 적이 있다는 것을 알고 있지만 이는 약간 다릅니다. 이스케이프된 주석 #이나 시작 주석을 의미하지 않는 주석(단일 또는 이중 정점 사이)을 제외한 모든 주석을 제거해야 합니다.

다음 텍스트로 시작하세요.

test
# comment
comment on midline # comment
escaped hash "\# this is an escaped hash"
escaped hash "\\# this is not a comment"
not a comment "# this is not a comment - double apices"
not a comment '# this is not a comment - single apices'
this is a comment \\# this is a comment
this is not a comment \# this is not a comment

난 갖길 원해

test
comment on midline
escaped hash "\# this is an escaped hash"
escaped hash "\\# this is not a comment"
not a comment "# this is not a comment - double apices"
not a comment '# this is not a comment - single apices'
this is a comment \\
this is not a comment \# this is not a comment

나는 노력했다

grep -o '^[^#]*' file

그러나 이렇게 하면 이스케이프된 해시도 제거됩니다.

참고: 제가 다루고 있는 텍스트는 실제로 이스케이프 #( \#)되었지만 이중 이스케이프 #( \\#)가 부족하므로 보존 여부는 중요하지 않습니다. 해시가 이스케이프되지 않는다는 사실 때문에 제거하는 것이 더 깨끗할 것이라고 생각합니다.

답변1

a (0개 이상의 공백이 앞에 오는) sed로 시작하는 줄을 제거하고 , 그 뒤에 단일 백슬래시가 없는(따옴표 1 사이에 있지 않은 경우에만 ) 그것으로 시작하는 모든 문자열을 제거 할 수 있습니다.##

sed '/^[[:blank:]]*#/d
/["'\''].*#.*["'\'']/!{
s/\\\\#.*/\\\\/
s/\([^\]\)#.*/\1/
}' infile

1: 이 솔루션은 한 줄에 따옴표 쌍이 있다고 가정합니다.

답변2

이는 보기보다 더 복잡한 문제이지만 정규식의 기능을 넘어서는 것은 아닙니다. 분석해 보세요. 전체 줄은 주석이 아닌 텍스트로 구성되며 선택적으로 주석 텍스트가 뒤따릅니다. 주석이 아닌 텍스트에 나타날 수 있는 내용:

  1. , \, #, '를 제외한 모든 문자"
  2. \그 뒤에 임의의 문자가 옵니다.
  3. and 로 시작하고 끝나는 따옴표 붙은 문자열 "(다음을 포함할 수 있음)
    • \가) 또는를 제외한 모든 문자"
    • B) \뒤에 임의의 문자가 옵니다.
  4. and 로 시작하고 끝나는 따옴표 붙은 문자열 '(다음을 포함할 수 있음)
    • 제거하다'

(두 참조 모두 유닉스 쉘이 처리하는 방식에 따라 다르게 처리됩니다. 취향에 맞게 조정하세요.)

이것을 정규식으로 직접 변환하려면 다음이 필요합니다.

s/^([non comment])[comment]$/\1/
non comment = ([^\\"'#]|\\.|"([^\\"]|\\.)*"|'[^']*')*
              (11111111|222|3(AAAAAA|BBB)33|4444444)*
comment = #.*
Therefore
s/^(([^\\"'#]|\\.|"([^\\"]|\\.)*"|'[^']*')*)#.*$/\1/

sed정규식의 경우 및 문자 앞에 백슬래시를 더 추가 해야 합니다 .(|)

s/^\(\([^\\"'#]\|\\.\|"\([^\\"]\|\\.\)*"\|'[^']*'\)*\)#.*$/\1/

Bash에는 추가 따옴표가 필요합니다.

sed 's/^\(\([^\\"'\''#]\|\\.\|"\([^\\"]\|\\.\)*"\|'\''[^'\'']*'\''\)*\)#.*$/\1/'

grep -o편집: @StéphaneChazelas의 답변을 보기 전까지는 이것이 존재한다는 것을 몰랐습니다. 동일한 핵심 정규식을 이 접근 방식에 적용할 수 있으며 egrep을 사용하면 추가 백슬래시를 대부분 수행하지 않아도 됩니다.

grep -Eo '^([^\\"'\''#]|\\.|"([^\\"]|\\.)*"|'\''[^'\'']*'\'')*'
grep -Eo "^([^\\\\\"'#]|\\\\.|\"([^\\\\\"]|\\\\.)*\"|'[^']*')*"

이 둘은 의미가 동일하고(길이도 동일함) 쉘 인용의 다른 방법일 뿐입니다. 저는 개인적으로 작은 따옴표가 걱정해야 할 유일한 문자이므로 첫 번째 방법을 선호하지만 두 번째 방법이 더 읽기 쉽다는 것을 알 수 있습니다. , 이는 다른 프로그래밍 언어로 작성하는 것과 매우 유사합니다.

정규식은 일치하지 않는 따옴표가 포함된 줄을 어떻게 처리할지 알 수 없다는 점에 유의하는 것이 중요합니다. 정규식과 전혀 일치하지 않으므로 sed 명령은 아무것도 삭제하지 않지만 grep 명령은 모든 것을 삭제합니다.

답변3

이 명령이 작동해야 합니다.

sed -e '/^#/d;s/[^\/]#.*$//' <file-path>

관련 정보