파일에서 모든 주석을 제거하려면 어떻게해야합니까?


21

의견이있는 파일이 있습니다.

foo
bar
stuff
#Do not show this...
morestuff
evenmorestuff#Or this

주석 처리되지 않은 모든 코드를 인쇄하고 싶습니다.

foo
bar
stuff
morestuff
evenmorestuff

파일에서 주석을 제거 할 수있는 것이 매우 중요합니다.이를 수행하는 좋은 방법은 무엇입니까?


1
grep을 사용하여 라인의 일부를 제거 할 수 없습니다. 당신은 이것을 위해 sed를 사용할 수 있습니다
miracle173

2
텍스트와 예제가 모순됩니다. 주석 처리 된 행에 대해 쓰지만 마지막 행에서 분명히 선 부분을 의미합니다. 그리고 주석이있는 첫 번째 행은 EOL을 포함하여 삭제되고 두 번째 두 번째 행은 삭제 될 수 있지만 마지막 행이므로 명확하지 않습니다. '줄이 주석 처리 된 줄'을 정확하게 바꾸고 예를 명확하게하십시오.
Anthon

5
를 사용해보십시오 awk -F\# '$1!="" { print $1 ;} '.
Archemar

2
같은 라인은 어떻게 echo '#' # output a #처리됩니까?
Kusalananda

3
@Questionmark 나는 영리하지만 어쩌면 쉘 문법 파서 영리하지 않습니다.
Kusalananda

답변:


40

모든 주석을 제거하는 한 가지 방법은 옵션 grep과 함께 사용 하는 -o것입니다.

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

어디에

  • -o: 줄의 일치하는 부분 만 인쇄합니다
  • first ^: 줄의 시작
  • [^#]*: #0 번 이상 반복 된 것을 제외한 모든 문자

빈 줄도 제거되지만 공백 만있는 줄은 유지됩니다.


2
나는 사용합니다grep -v '^#' file > newfilewithoutcomments
Basile Starynkevitch

1
예를 들어 행 somvar='I am a long complicated string ## with special characters' # and I am a comment이 올바르게 처리되지 않으므로 쉘 스크립트의 일반적인 방법 이 아닙니다.
와일드 카드

이 변형은 Mac에서 더 잘 작동합니다.grep -o '^[^#].*' file
Pierz

의견이 사라졌지 만 출력에서 ​​자신의 자리에 공백이 많이 있습니까? sed솔루션에는 빈 줄이 하나만 있는데, 뭔가 빠지지 않는 한 다른 대답을 사용하는 확실한 주장처럼 보입니다.
JBallin

@JBallin grep아마도 별명을 정의 했습니까 ? 변경 시도 grepcommand grep여전히 공백 샘플 입력을 게시 보면,.
jimmij

31

나는 sed이것보다 훨씬 더 나은 일을 할 수 있다고 믿는다 grep. 이 같은:

sed '/^[[:blank:]]*#/d;s/#.*//' your_file

설명

  • sed기본적으로 파일을 한 줄씩보고 따옴표로 변환을 적용한 후 각 줄을 인쇄합니다. ( sed '' your_file모든 행을 변경하지 않고 인쇄합니다).
  • 여기서 우리는 sed각 줄에서 수행 할 두 가지 명령을 제공 합니다 (세미콜론으로 구분).
  • 첫 번째 명령은 다음과 같습니다 /^[[:blank:]]*#/d.. 영어로, 그 줄이 처음에 해시와 일치하면 (앞에 여러 개의 공백이 있음) 해당 줄을 삭제하십시오 (인쇄되지 않음).
  • 두 번째 명령은 다음과 같습니다 s/#.*//. 즉 영어에서는 해시 마크로 대체 할 수있는만큼 (줄이 끝날 때까지) 아무것도없는 것 (마지막 두 개 사이의 빈 공간은 없음)을 대체하십시오 //.
  • 요약하면, 이것은 주석으로 구성된 줄을 삭제하는 줄과 그 뒤에 남겨진 줄을 삭제하는 파일을 통해 실행됩니다.

1
또한 문자열 안에서 해시 후에 발견 된 모든 것을 삭제합니다 . 예가 mystring="Hello I am a #hash" 될 것입니다 mystring="Hello I am a"
javadba

@ javadba, 그렇습니다. 그러나 그 시점에서 전체 파서를 사용할 수도 있습니다. 따옴표와 변수 할당을 이해할 있지만 주석을 처리 할 수없는 이 데이터를 사용하게 될 것은 무엇입니까 ? (이것은 crontab선행 공백 유무에 관계없이 전체 줄 주석 만 허용하지만 줄에 후행 주석을 허용하지 않는 것과 같은 많은 구성 파일 입니다. 논리는 훨씬 간단합니다.이 답변의 두 Sed 명령어 중 첫 번째 만 사용하십시오. crontab 주석 스트리퍼.)
와일드 카드

큰 대답은 광범위한 일반적인 사용 사례에서 유틸리티와 복잡성의 균형이 잘 잡힌 것처럼 보이지만 사전에 #(1 열)으로 시작하는 행만 삭제해야한다는 것을 미리 알고있는 경우 , sed이상에 어떤 이점이 grep -v "^#"있습니까?
RBF06

4

sed 명령을 사용하여 필요한 출력을 얻을 수 있습니다. 아래 명령은 나를 위해 속임수를 사용했습니다.

sed 's/#.*$//g' FileName

어디에

  • #.*$-Regexp는 #줄 끝까지 시작하는 모든 문자열을 필터링합니다.

여기서 우리는 그 줄을 제거하여 비어있는 것으로 바꾸어 '교체'부분을 건너 뜁니다.

  • g -파일 끝에 도달 할 때까지 패턴의 반복 검색을 언급합니다.

sed의 일반적인 문법 : s/regexp/replacement/flags FileName


2
참고 :이 경우 4 번째 줄이 새 줄로 바뀝니다.
αғsнιη

1
sed명령을 포함하는 스크립트로 시도해보십시오 ...
Kusalananda

처리하지 않습니다print "#tag" # Print a hashtag.
Ray Butterworth

3

다른 사람들이 지적했듯이 스크립트의 일부가 주석처럼 보이지만 실제로는 그렇지 않으면 sed 및 기타 텍스트 기반 도구가 제대로 작동하지 않습니다. 예를 들어 문자열 안에서 #을 찾거나 다소 공통적 인 $#및을 찾을 수 ${#param}있습니다.

코드를 축소 하는 기능이있는 shfmt 라는 쉘 포맷터를 작성했습니다 . 여기에는 무엇보다도 주석 제거가 포함됩니다.

$ cat foo.sh
echo $# # inline comment
# lone comment
echo '# this is not a comment'
[mvdan@carbon:12] [0] [/home/mvdan]
$ shfmt -mn foo.sh
echo $#
echo '# this is not a comment'

파서와 프린터는 Go 패키지이므로 사용자 지정 솔루션을 원하는 경우 원하는 방식으로 주석을 제거하기 위해 20 줄 Go 프로그램을 작성하는 것이 매우 쉽습니다.


2

다음과 같이 반전 일치를 사용할 수 있습니다.

    #grep -v "#" filename

-v, --invert-match 일치하는 의미를 반전시켜 일치하지 않는 행을 선택합니다. (-v는 POSIX에 의해 지정됩니다.)


2
@alinh 답변을 검토해 주셔서 감사합니다. 질문은 줄의 시작뿐만 아니라 파일의 어느 곳에서나 필요했습니다. 이것은 또한 위의 질문에 예상 결과로 표시됩니다. 줄의 시작 부분 만 찾으면 대답이 정확하지 않습니다.
Raza

쿨쿨. 내 나쁜, 마지막 줄을 보지 못했다 :(
alinh

1
이것은 evenmorestuffOP의 예에서 시작하는 줄을 완전히 제거합니다 .
조셉 R.

@JosephR. 잘 잡는다. 나는 이전에 그것을 놓쳤다. 이 경우 grep -o '^[^#]*' file최상의 솔루션이 될 것입니다. 이것은 이미 jimmij에 의해 설명되었습니다. 검토해 주셔서 감사합니다
Raza

처리되지 않습니다 print "#tag" # Print a hashtag.
Ray Butterworth

2

나는 조셉의 대답을 좋아하지만 // 주석을 제거해야했습니다. 그래서 약간 수정하고 redhat에서 테스트했습니다.

# no comments alias
alias nocom="sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' | strings"

# example
cat SomeFile | nocom | less

문자열을 사용하는 것보다 빈 줄을 제거하는 더 좋은 방법이 있지만 내 생각에는 빠르고 더러운 솔루션이었습니다.

-건배


처리하지 않습니다print "#tag" # Print a hashtag.
Ray Butterworth


1
cat YOUR_FILE | cut -d'#' -f1

#열 구분 기호로 사용 하고 첫 번째 열만 유지합니다 (이전의 모든 것 #).


1
YOUR_FILE해당 명령이 포함 된 스크립트 인 경우 cat YOUR_FILE | cut -'해당 줄의 파일에 스크립트가 남습니다 .
Kusalananda

1

다음과 같은 표현 사용

egrep -v "#|$^" <file-name> 

: -v : 반전 일치

: # : #으로 시작하는 모든 줄과 일치

: $ ^ : 모든 빈 줄과 일치


1
아니요,은 #라인의 모든 위치와 일치하며 전체 라인을 제거합니다.
ilkkachu

1

가장 좋은 해결책은 다음 명령을 사용하는 것입니다.

sed -i.$(date +%F) '/^#/d;/^$/d' ntp.conf

-i는 전체 편집이지만 접두어 바로 뒤에 오는 접두어는 백업을 작성하도록 지시합니다. 이 경우 날짜 확장명 (ntp.conf.date)을 사용하여 주소 공간이있는 두 개의 명령을 실행합니다. 첫 번째는 주석 처리 된 행을 삭제하고 두 번째 명령은 세미콜론으로 구분하고 빈 행을 삭제합니다.

이 솔루션을 찾았습니다 : theurbanpenguin.com


0

다른 답변은이 정의를 수행하는 것 같지 않습니다. 빈 줄이나 주석이 첫 문자가 아닌 줄에 두십시오. 나는 이것을 사용하여 끝났다.

cat << EOF >> ~/.bashrc
alias nocom='sed -e "/^\s*#/d" -e "/^\s*$/d"'
EOF

이렇게하면 별칭을 설정하므로 암기 할 필요가 없습니다 (처음에는 불가능합니다). 새 세션을 열면 새로운 nocom명령이 나타납니다. 그럼 당신은 할 수 있습니다

nocom /etc/foobar.conf

건배.


1
.*$첫 번째 정규 표현식 에는 일치 할 점이 많지 않습니다 . 앵커는 유용하지 않으며 대체 할 텍스트를 캡처하지 않습니다. 그냥 사용하십시오^\s*
Jeff Schaller

처리하지 않습니다print "#tag" # Print a hashtag.
Ray Butterworth

0

Joseph R.의 두 번째 답변에 이어 /^$/d빈 줄을 제거합니다.

sed '/^[[:blank:]]*#/d;s/#.*//;/^$/d'

-1

나는 나를 위해 일하는 것을 게시하고 있으며 설명을 통해 다른 사람들을 읽은 후 가장 의미가있는 것처럼 보입니다. 몇 개의 게시물이 가까워졌지만 아직 댓글을 달 수 없었습니다 (새로운 친구이기 때문에).

grep -E -v "(^#.*|^$)" filename
  • -E = egrep를 사용하는 것과 비슷한 다음 패턴을 정규식으로 해석
  • -v = 패턴의 반전을 인쇄합니다 (표현식과 일치하지 않는 행이 인쇄 됨)
  • "(^#.*|^$)"= OR 문을 지정하는 파이프가 있습니다. 이 표현식은 #(및 그 뒤의 다른 항목)으로 시작하는 행이나 행의 시작과 끝 사이에 문자 가없는 행을 인쇄한다고 말합니다 .

-v화면에로 시작하지 않는 자와 어떤 라인이 될 것이다의 반전을 출력 할 것이다 #.


처리하지 않습니다print "#tag" # Print a hashtag.
Ray Butterworth

아, 물론 ... 지적 해 주셔서 감사합니다. pam.d configs와 같은 일반적인 Linux 구성 파일과 관련하여 답을 찾고 있었으므로 생각하지 않았습니다. 코드와 같은 줄에있는 주석을 찾아 제거하려면 조정해야한다고 생각합니다. 방금 위의 특정 문제에 대한 더 나은 해결책을 보았습니다. egrep -v "# | $ ^"
jackbmg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.