이 질문이 이전에 요청된 적이 있다는 것을 알고 있지만 이는 약간 다릅니다. 이스케이프된 주석 #
이나 시작 주석을 의미하지 않는 주석(단일 또는 이중 정점 사이)을 제외한 모든 주석을 제거해야 합니다.
다음 텍스트로 시작하세요.
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
이는 보기보다 더 복잡한 문제이지만 정규식의 기능을 넘어서는 것은 아닙니다. 분석해 보세요. 전체 줄은 주석이 아닌 텍스트로 구성되며 선택적으로 주석 텍스트가 뒤따릅니다. 주석이 아닌 텍스트에 나타날 수 있는 내용:
- ,
\
,#
,'
를 제외한 모든 문자"
\
그 뒤에 임의의 문자가 옵니다.- and 로 시작하고 끝나는 따옴표 붙은 문자열
"
(다음을 포함할 수 있음)\
가) 또는를 제외한 모든 문자"
- B)
\
뒤에 임의의 문자가 옵니다.
- 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>