Sed 명령은 주석이 달린 일치 항목을 무시합니다.

Sed 명령은 주석이 달린 일치 항목을 무시합니다.

텍스트 파일에 주석이 없을 경우에만 이를 대체하기 위해 정규식을 사용하여 sed 명령을 생성하려고 하는데 sed 명령에 대해 아는 바가 거의 없기 때문에 문제가 발생합니다.

문제의 작은 부분에 대한 해결책을 찾았지만 일부는 충분하지 않거나 하나로 통합할 수 없습니다.TL;DR 버전은 마지막에 제공됩니다.

먼저 나의 궁극적인 목표를 결정해야 합니다.

텍스트 파일의 모든 항목과 일치시키고 싶습니다(일반 정규식(헤헤)).아니요댓글을 달았습니다. 여러 언어에 대해 이 작업을 수행하고 싶기 때문에 일반적인 C 주석만 사용하겠습니다.

따라서 이 경우 단어나 줄에 다양한 방식으로 주석을 달 수 있습니다. 다음에 나올 내용에 대해서만 댓글을 달 수 있으며 댓글 블록 //도 있습니다 ./* */


환경

저는 현재 POSIX sed만 지원하는 Mac OSX를 사용하고 있지만 GNU-sed를 설치했는데 더 나은 것 같습니다. (감사합니다 Homebrew. 패키지는 이고 gnu-sed명령은 입니다 gsed.) 따라서 둘 중 하나를 사용하고 싶으시면 둘 다 사용할 수 있습니다.

나는 GNU-sed를 사용한다는 가정하에 이 글을 쓴다.


사건을 무시하다

첫 번째 질문은 특정 상황을 무시하는 방법입니다. 나는 쉽다고 생각했다.이 주제.

이제 이 //부분은 나에게 쉬운 것 같습니다.또는( |)조건은 다른 조건과 결합됩니다.

다음과 같습니다.

    sed -E "/\/\/.*/! s/foo/bar/" file

따라서 입력 파일이 다음과 같은 경우:

foo
42
test
//foo
//42
//    foo
//something foo
foo
42
something foo
  foo

출력은 다음과 같습니다

bar
42
test
//foo
//42
//    foo
//something foo
bar
42
something bar
  bar

/* */그래서 지금은 댓글 섹션 에 내 생각을 집중하고 싶습니다 .


여러 줄에 걸쳐 일치

두 번째 질문은 정규식을 여러 줄에서 일치시키는 방법입니다. 글쎄, 내 생각엔 그게 가장 큰 문제인 것 같아. 내가 찾은이 주제개행 문자로만 일치시키는 방법에 대해 토론합니다. 글쎄, 그것이 어떻게 작동하는지 알아내는 데 시간이 좀 걸렸습니다. 하지만 이 부분의 해결책은 나에게 새로운 문제와 새로운 질문을 안겨주었습니다.

분명히 새 줄( \n)만 무시할 수 있습니다. 그래서 이제 동일한 작업을 수행하고 싶지만 행 수는 알 수 없습니다(0에서 무한대( *)까지). 줄을 반복해야 할 것 같지만 sed의 명령에 대해 아무것도 모르고 이것이 정말 어색하기 때문에 여기서 막히게 됩니다.

검색하다가 한 가지를 발견했습니다.작은 스크립트목적은 tail명령을 대체하는 것이며 루프를 사용하지만(아마도) 그것이 무엇을 하는지 이해할 수 없습니다.

*/해당 부분 이전에만 일치하게 하세요.

세 번째 부분은 무시된 대소문자가 주석 블록 끝( */) 앞에 오는 내용과만 일치하는지 확인하는 것입니다. 따라서 궁극적으로 대소문자를 무시하면 /*과 사이의 모든 항목 과만 일치합니다 */. 최종 명령은 주석 블록에 작성된 내용을 완전히 무시합니다.

제가 이 부분에 대해서는 실제 검색을 하지 않은 이유는 이전 사항을 다루지 않았으며 이 질문은 이전 질문 */에 달려 있는 것 같습니다 ./*


마지막 부분: 모든 것을 하나로 합치기

글쎄, 분명히 나는 ​​이 시점에서 완전한 실패자다.


긴 이야기 짧게

내 질문은: 주석 없이 텍스트 파일에서 원하는 것을 바꾸는 sed 명령은 무엇입니까?


부록

다른 언어를 사용하는 더 쉬운 방법을 알고 있다면 그것도 매우 환영합니다. 따라서 이 작업을 수행하는 방법이나 다른 방법을 알고 계시다면 awk언제든지 python공유해 주세요.

답변1

그들이 불가능하다고 말하면 믿어서는 안됩니다. 너~해야 한다그러나 그들이 당신에게 말하면 믿으십시오.쉽지 않습니다.

sed '\|*/|!{ s|/\*|\n&|              #if ! */ repl 1st /* w/ \n/*
     h;      s|foo|bar|g;/\n/!b      #hold; repl all foo/bar; if ! \n branch
     G;      s|\n.*\n||;:n           #Get; clear difference; :new label
     n;      \|*/|!bn;s|^|\n/*|      #new line; if ! */ branch new label
     };s|*/|\n&|g                    #repl all */ w/ \n*/
       s|foo|&\nbar|g;:r             #repl all foo w/ foo\nbar
       s|\(/\*[^\n]*\)\nbar|\1|g;tr  #repl all /*[^\n]*\nbar w/ foo
       s|foo\n\(b\)|\1|g             #repl all foo\nbar w/ bar
       s|^\n/.||;s|\n||g             #clear any \n inserts
'    <<\INPUT
asfoo   /* asdfooasdfoo


asdfasdfoo
asdfasdfoo
foo */foo /*foo*/ foo
/*.
foo*/
foo
hello

INPUT

산출

asbar   /* asdfooasdfoo


asdfasdfoo
asdfasdfoo
foo */bar /*foo*/ bar
/*.
foo*/
bar
hello

관련 정보