Muster finden und aus allen Dateien entfernen

Muster finden und aus allen Dateien entfernen

Bitte helfen Sie mir, das folgende Problem zu lösen. Entfernen Sie alle Zeichenpaare \ naus Test_Macro in allen Dateien. Siehe folgendes Beispiel:

Fil1.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...

dir1/File2.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...

Erwartetes Ergebnis:

Datei1.txt

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

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

dir1/File2.txt

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

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

Ich bin für jede Hilfe und jeden Vorschlag dankbar. Ich habe vor, ein Skript zu schreiben. Denn ich habe viele verschiedene Dateitypen und viele solcher Makros. Vielen Dank im Voraus!

Die Argumente für Test_Macro können verschachtelte Aufrufe anderer Makros enthalten und können beliebige Zeichen innerhalb von Zeichenfolgen enthalten.

Antwort1

Es gibt einen Satz, den man sich merken sollte: „Reguläre Ausdrücke können nicht zählen.“

Dies ist in diesem Fall wichtig, da viele „einfache“ Unix-Tools auf regulären Ausdrücken basieren. Hier werden die öffnenden und schließenden Klammern („runde Klammern“) gezählt, die in den Argumenten für Test_Macro verwendet werden können.

Wenn die Aufrufe von Test_Macroniemalsverschachtelte Klammern haben, dann gibt es einen einfachen Trick. Ändern Sie zunächst jedes )Zeichen in ein Newline-Zeichen und umgekehrt. Löschen Sie dann jede Zeile, die kein Test_Macro enthält, und entfernen Sie alles bis zum Test_Macro. An diesem Punkt würde ein Teil der verarbeiteten Datei2.txt so aussehen

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

Jetzt müssen wir also die Rückseite konvertieren ). An diesem Punkt haben Sie mehrere Möglichkeiten. Ich bevorzuge die Verwendung von sed, um die zusätzlichen Leerzeichen gleichzeitig zu entfernen. Wir müssen auch die Rückseite )und vielleicht die;

Zusammengefasst haben wir

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

Wenn die Möglichkeit besteht, dass die Argumente für Test_Macro verschachtelte Klammern enthalten, müssen Sie deutlich größere Geschütze auffahren, da Sie die Eingabe analysieren und nicht nur ein Mustervergleich durchführen müssen. (Theoretisch können Sie ein Mustervergleich durchführen, wenn Sie die Verschachtelungsebene einschränken können, aber in der Praxis wird dies sehr schnell sehr, sehr kompliziert und Sie sollten diesen Ansatz verwerfen.) Es gibt Parser-Frameworks für Sprachen wie Python, oder Sie können Tools auf der Grundlage von Tools wie Lex erstellen.

Antwort2

Bearbeiten: Diese Antwort wurde erstellt, bevor die Frage überarbeitet wurde. Die ursprüngliche Form der Frage enthielt:

Als ich versuchte, mit „grep“ ein Muster zu finden, wurde nur die erste Zeile gedruckt. Ich wollte aber bis zum Ende der Klammer.

Reguläre Ausdrücke können nicht zählen, aber Sed kann eine Schleife ausführen.

Test_MacroHier ist ein Sed-Ausschnitt, der von jeder Zeile bis zur Zeile mit der entsprechenden schließenden Klammer greift ,auch wenn Klammern verschachtelt sind:

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

In einen Einzeiler umgewandelt sieht das so aus:

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

Eingabe und Ausgabe sehen folgendermaßen aus:

$ 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");
$ 

Antwort3

Datei1:

$ 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");

Datei2:

$ 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: Der einfachste Weg, alle Zeilenumbrüche zu entfernen, ist:

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

ohne Zeilenumbrüche;

$ 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");

ohne "\n" aber mit Zeilenumbrüchen... lol

$ 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");

Entfernen Sie einfach die Zeichenfolge „\n“ (und das nachstehende Leerzeichen).

$ 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...

noch einmal (hoffentlich das letzte Mal) ... Entfernen der Zeichenfolge „\n“, wenn sie sich in der Funktion Test_Macro befindet, aber nicht außerhalb, und keine Entfernen von Zeilenumbrüchen;

$ 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...

aktualisieren;

$ 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...

verwandte Informationen