Bitte helfen Sie mir, das folgende Problem zu lösen. Entfernen Sie alle Zeichenpaare \
n
aus 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_Macro
Hier 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...