Ich habe sed und awk ausprobiert, aber es funktioniert nicht, da es sich bei dem Zeichen um "/" handelt, das bereits als Trennzeichen im Befehl steht.
Bitte lassen Sie mich wissen, wie ich dies erreichen kann.
Unten sehen Sie ein Beispiel. Wir möchten die kommentierten Abschnitte entfernen, d. H /*.....*/
/*This is to print the output
data*/
proc print data=sashelp.cars;
run;
/*Creating dataset*/
data abc;
set xyz;
run;
text-processing
Sharique Alam
quelle
quelle
INSERT INTO string_table VALUES('/*'), ('*/'), ('/**/');
)Antworten:
Ich denke, ich habe eine einfache Lösung gefunden!
EINIGE UPDATES:
Zitat des Benutzers ilkachu (Originaltext aus den Benutzerkommentaren):
Ich habe ein bisschen mit den Optionen für gcc gespielt: -fpreprocessed deaktiviert die meisten Direktiven und Makro-Erweiterungen (außer anscheinend #define und #undef). Das Hinzufügen von -dD hinterlässt ebenfalls defined in. und std = c89 können verwendet werden, um // neue Stilkommentare zu ignorieren. Selbst mit ihnen ersetzt cpp Kommentare durch Leerzeichen (anstatt sie zu entfernen) und reduziert Leerzeichen und leere Zeilen.
Aber ich denke, es ist immer noch vernünftig und eine einfache Lösung für die meisten Fälle, wenn Sie die Makroerweiterung deaktivieren und andere Dinge, von denen ich denke, dass Sie gute Ergebnisse erzielen ... - und ja, Sie können das mit Shell-Skript kombinieren, um besser zu werden ... und vieles mehr...
quelle
cpp
wird viel mehr als das Entfernen von Kommentaren (Verarbeiten#include
, Erweitern von Makros, einschließlich eingebauter Makros ...)tail -n +7
nur die ersten 7 Zeilen und verhindert nicht die#include
Verarbeitung oder Makroerweiterungen. Versuchen Sie esecho __LINE__ | cpp
zum Beispiel. Oderecho '#include /dev/zero' | cpp
-P
Modus verwenden. (Dies kann die Notwendigkeit der Verwendung beseitigentail
.)-fpreprocessed
Deaktiviert die meisten Direktiven und Makro-Erweiterungen (außer#define
und#undef
anscheinend). Durch-dD
das Hinzufügen bleiben auch die Definitionen erhalten. undstd=c89
können verwendet werden, um neue//
Stilkommentare zu ignorieren . Ersetzt auch bei ihnencpp
Kommentare durch Leerzeichen (anstatt sie zu entfernen) und reduziert Leerzeichen und leere Zeilen.Ich kam einmal mit bis diese , die wir verfeinern:
um ein paar weitere Eckfälle zu behandeln.
Beachten Sie, dass , wenn Sie entfernen einen Kommentar, können Sie die Bedeutung des Codes ändern könnten (
1-/* comment */-1
wird wie analysiert ,1 - -1
während1--1
(die Sie erhalten würden , wenn Sie den Kommentar entfernt) würden Sie einen Fehler). Es ist besser, den Kommentar durch ein Leerzeichen zu ersetzen (wie wir es hier tun), als ihn vollständig zu entfernen.Das Obige sollte zum Beispiel mit diesem gültigen ANSI-C-Code funktionieren, der versucht, einige Eckfälle einzuschließen:
Was gibt diese Ausgabe:
Beide drucken beim Kompilieren und Ausführen dieselbe Ausgabe.
Sie können mit der Ausgabe von vergleichen, um
gcc -ansi -E
zu sehen, was der Vorprozessor damit machen würde. Dieser Code ist auch gültig für C99- oder C11-Code,gcc
deaktiviert jedoch standardmäßig die Trigraph-Unterstützung, sodass er nur funktioniert,gcc
wenn Sie den Standard wiegcc -std=c99
oder angebengcc -std=c11
oder die-trigraphs
Option hinzufügen .Es funktioniert auch mit diesem C99 / C11-Code (kein ANSI / C90-Code):
(vergleiche mit
gcc -E
/gcc -std=c99 -E
/gcc -std=c11 -E
)ANSI C hat den
// form
Kommentar von nicht unterstützt .//
ist in ANSI C sonst nicht gültig und wird dort nicht angezeigt. Ein erfundener Fall//
, in dem ANSI C möglicherweise wirklich vorkommt (wie dort angegeben , und Sie den Rest der Diskussion vielleicht interessant finden), ist, wenn der Operator stringify verwendet wird.Dies ist ein gültiger ANSI C-Code:
Und zum Zeitpunkt der Diskussion im Jahr 2004 hat
gcc -ansi -E
es sich in der Tat erweitert"//not a comment"
. Gibt jedoch heutegcc-5.4
einen Fehler zurück, sodass ich bezweifle, dass wir mit dieser Art von Konstrukt viel C-Code finden werden.Das GNU-
sed
Äquivalent könnte etwa so lauten:Wenn Ihre GNU
sed
zu alt ist, um-E
oder zu unterstützen-z
, können Sie die erste Zeile ersetzen durch:quelle
gcc -std=c11 -E -P
(-ansi
ist nur ein anderer Name für-std=c90
).??'
) zu handhaben , daher vergleichen wir mitcpp -ansi
denen und C99 / C11 ... einem (wie// xxx
), daher vergleichen wir mitcpp
(odercpp -std=c11
...)mit
sed
:AKTUALISIEREN
unterstütze alles Mögliche (mehrzeiliger Kommentar, Daten nach [oder und] vorher,);
Lauf:quelle
proc print data 2nd /*another comment is here*/
Entfernen Sie leere Zeilen, falls vorhanden:
Edit - die kürzere Version von Stephane:
quelle
-0777
als kürzeren WegBEGIN{$/=undef}
.*?
statt.+?
if auch/**/
ein gültiger Kommentar.Lösung mit SED-Befehl und ohne Skript
Hier sind Sie ja:
sed 's/\*\//\n&/g' test | sed '/\/\*/,/\*\//d'
Hinweis: Dies funktioniert nicht unter OS X, es sei denn, Sie installieren
gnu-sed
. Aber es funktioniert unter Linux Distros.quelle
-i
Option verwenden, um die Datei direkt zu bearbeiten, anstatt die Ausgabe in eine neue Datei umzuleiten. oder viel sicherer-i.bak
Backup-Dateised
Wird jeweils in einer Zeile ausgeführt, aber einige der Kommentare in der Eingabe erstrecken sich über mehrere Zeilen. Gemäß /unix//a/152389/90751 können Sie zuersttr
die Zeilenumbrüche in ein anderes Zeichen umwandeln. Anschließendsed
können Sie die Eingabe als einzelne Zeile verarbeiten undtr
erneut verwenden, um die Zeilenumbrüche wiederherzustellen.Ich habe Null-Bytes verwendet, aber Sie können jedes Zeichen auswählen, das nicht in Ihrer Eingabedatei enthalten ist.
*
Hat in regulären Ausdrücken eine besondere Bedeutung, so dass ein Escapezeichen erforderlich ist,\*
um ein Literal zu finden*
..*
ist gierig - es wird mit dem längsten möglichen Text übereinstimmen, einschließlich mehr*/
und/*
. Das bedeutet den ersten Kommentar, den letzten Kommentar und alles dazwischen. Um dies einzuschränken, ersetzen Sie es.*
durch ein strengeres Muster: Kommentare können alles enthalten, was kein "*" ist, und auch "*", gefolgt von allem, was kein "/" ist. Läufe von mehreren*
s müssen auch berücksichtigt werden:Dadurch werden alle Zeilenumbrüche in den mehrzeiligen Kommentaren entfernt, d. H.
wird werden
Wenn dies nicht das ist, was gewünscht wurde,
sed
kann gesagt werden, einen der Zeilenumbrüche beizubehalten. Dies bedeutet, dass Sie ein Zeilenumbruch-Ersetzungszeichen auswählen, das abgeglichen werden kann.Es
\f
ist nicht garantiert, dass das Sonderzeichen und die Verwendung eines Verweises, der möglicherweise nicht mit irgendetwas übereinstimmt, in allensed
Implementierungen wie beabsichtigt funktionieren . (Ich habe bestätigt, dass es unter GNU sed 4.07 und 4.2.2 funktioniert.)quelle
test.sas
in die Mitte der Pipeline gestellt,sed
liest also direkt daraus und die erstetr
hat keine Auswirkung. Sie müssen verwendencat test.sas | tr ...
Verwenden Sie eine Zeile sed, um Kommentare zu entfernen:
quelle