패턴을 찾아 모든 파일에서 제거 [닫기]

패턴을 찾아 모든 파일에서 제거 [닫기]

다음 문제를 해결하도록 도와주세요. \ n모든 파일의 Test_Macro에서 모든 문자 쌍을 제거합니다. 다음 예를 참조하세요.

1.txt를 입력하세요.

Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

디렉토리1/파일2.txt

Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n",
        123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

예상되는 결과:

파일 1.txt

Test_Macro(abc, def, " string1 string2 test string",
   "test string2 ");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

디렉토리1/파일2.txt

Test_Macro(abc, def, " string1 string2  test string",
   "test string2 ",
    123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

어떤 도움이나 조언이라도 대단히 감사하겠습니다. 나는 몇 가지 스크립트를 작성할 계획입니다. 다양한 유형의 파일과 그러한 매크로가 많기 때문입니다. 미리 감사드립니다!

Test_Macro의 인수는 다른 매크로에 대한 중첩된 호출일 수 있으며 문자열의 모든 문자를 포함할 수 있습니다.

답변1

"정규 표현식은 중요하지 않다"는 말을 기억하세요.

이 경우에는 많은 "간단한" 유닉스 도구가 정규식을 기반으로 하기 때문에 이것이 중요합니다. 여기서의 개수는 Test_Macro의 매개변수에 사용될 수 있는 왼쪽 및 오른쪽 대괄호("괄호")의 개수입니다.

Test_Macro를 호출하면안 돼요중첩된 괄호가 있으면 간단한 트릭이 있습니다. 먼저 )각 문자를 개행 문자로 변경하거나 그 반대로 변경합니다. 그런 다음 Test_Macro를 포함하지 않는 모든 줄을 삭제하고 Test_Macro 이전의 모든 줄을 삭제합니다. 이 시점에서 처리된 File2.txt의 일부는 다음과 같습니다.

Test_Macro(abc, def, " string1 string2 test string",)   "test string2 ",)    123456

이제 )다시 변환해야 합니다. 이 시점에는 몇 가지 옵션이 있습니다. 나는 여분의 공백을 제거하면서 sed를 사용하는 것을 선호합니다. 다시 추가해야 할 )수도 있습니다.;

이것을 종합하면,

find . -type f | while read -r fn
do
   < "$fn" tr ')\n' '\n)' | sed -n 's/.*Test_Macro(/Test_Macro(/p' | \
     sed 's/) */ /g;s/$/);/'
done

Test_Macro의 매개변수에 중첩된 괄호가 포함될 수 있는 경우 패턴 일치뿐만 아니라 입력을 구문 분석해야 하므로 더 큰 총을 꺼내야 합니다. (이론적으로 중첩 수준을 제한할 수 있으면 패턴 일치를 수행할 수 있지만 실제로는 매우 빠르게 복잡해지기 때문에 이 접근 방식을 포기해야 합니다.) Python과 같은 언어를 위한 파서 프레임워크가 있거나 lex와 같은 도구 위에 도구를 구축할 수 있습니다.

답변2

편집: 이 답변은 질문이 수정되기 전에 준비되었습니다. 질문의 원래 형식은 다음과 같습니다.

특정 패턴을 찾기 위해 "grep"을 사용하려고 하면 첫 번째 줄만 인쇄됩니다. 하지만 나는 브래킷이 끝날 때까지 원합니다.

정규식은 계산할 수 없지만 Sed는 반복할 수 있습니다.

Test_Macro다음은 적절한 닫는 괄호를 사용하여 to를 포함하는 모든 줄에서 가져오는 Sed 스니펫입니다 .중첩된 괄호가 있는 경우에도:

#n
/Test_Macro/{
  p;
  :rep
  s/([^()]*)//;
  trep
  /^[^(]*$/d;
  h;
  n;
  p;
  x;
  G;
  brep
}

한 줄의 코드로 변환하면 다음과 같습니다.

sed -n -e '/Test_Macro/{p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}'

입력과 출력은 다음과 같습니다.

$ cat temp 
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...
$ sed -n -e '/Test_Macro/{p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}' temp 
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
Test_Macro(asdsadas, "test String1");
$ 

답변3

파일 1:

$ sed '/Test_Macro/{N;$!N;s/.*\(Test_Macro[^)]*);\).*/\1/;p;};d' abc.txt
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
Test_Macro(asdsadas, "test String1");

파일 2:

$ sed '/Test_Macro/{N;$!N;s/.*\(Test_Macro[^)]*);\).*/\1/;p;};d' abc2.txt
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n",
        123456);
Test_Macro(asdsadas, "test String1");

ps. 모든 개행 문자를 제거하는 가장 쉬운 방법은 다음과 같습니다.

echo -e "line \n break" | tr "\n" " "

줄 바꿈이 없습니다.

$ sed ':a;N;$!ba;s/[^;]\n[ ]*/ /g;' abc2.txt  | grep Test_Macro
Test_Macro(abc, def, "\n string1 string2 \n test string" "test string2 \n" 123456);
Test_Macro(asdsadas, "test String1");

"\n"은 없는데 개행 문자가 있네요...ㅋㅋㅋ

$ sed '/Test_Macro/{N;$!N;s/[ ]*\\n//g;s/.*\(Test_Macro[^)]*);\).*/\1/;p;};d' abc2.txt
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
        123456);
Test_Macro(asdsadas, "test String1");

"\n" 문자열(및 후행 공백)만 제거하세요.

$ sed ':a;N;$!ba;s/\\n[ ]*//g;' abc2.txt
Test_Macro(abc, def, "string1 string2 test string",
       "test string2 ",
        123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

다시 한 번(마지막으로)... Test_Macro 함수 내부에서 "\n" 문자열을 제거합니다. 단, 함수 외부에서는 제거하지 말고 개행 문자를 제거하지 마십시오.

$ sed '{N;/Test_Ma/{s/[ ]*\\n//g;};s/\(Test_Macro[^)]*);\)/\1/};' abc2.txt
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
        123456);
// Some code or text \n

Test_Macro(asdsadas, "test String1");
// Some code...

고쳐 쓰다;

$ sed '{:a;N;/Test_Ma/{s/[ ]*\\n//g;};ta};' abc2.txt 
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
        123456);
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n

Test_Macro(asdsadas, "test String1");
// Some code...

관련 정보