Re: awk/shell-Rätsel

From: Oliver Fromme <olli(at)lurza.secnetix.de>
Date: Wed, 14 Jan 2009 08:36:13 +0100 (CET)

Marc Santhoff wrote:
> #!/bin/sh
>
> awk '{ gsub(/</, "\\&lt;"); \
> gsub(/>/, "\\&gt;"); \
> gsub(/&/, "\\&amp;"); \
> gsub(/"/, "\\&quot;"); \
> gsub(/\'/, "\\&apos;"); \
> print }' -

Da ist noch ein kleiner Fehler: Das "&" musst Du als
allererstes konvertieren. Sonst wird nämlich aus einem
">" zuerst ein "&gt;" und in der nächsten Zeile sofort
ein "&amp;gt;", was sicherlich nicht beabsichtigt ist.

In /bin/sh kann man kann doppelte und einfache Anführungs-
zeichen wie folgt in sich selbst quoten:

   $ echo "foo\"bar"
   "
   $ echo 'foo'\''bar'
   '

Die vorletzte Zeile in Deinem Skript müsste also so aussehen:

   gsub(/'\''/, "\\&apos;")

Übrigens, die Semikolons und Backslashes an den Zeilenenden
sind überflüssig (schaden aber nicht); awk akzeptiert ein
Newline als Kommandotrenner.

Falls das Shellskript außer dem awk-Kommando nichts weiter
enthält, dann brauchst Du gar keine /bin/sh, sondern
kannst es direkt als awk-Skript schreiben, womit Du die
Quoting-Problematik der Shell ganz vermeidest:

#!/usr/bin/awk -f
{
    gsub(/&/, "\\&amp;")
    gsub(/</, "\\&lt;")
    gsub(/>/, "\\&gt;")
    gsub(/"/, "\\&quot;")
    gsub(/'/, "\\&apos;")
    print
}

Alternativ kannst Du ein sed-Skript nehmen, das etwa drei-
bis viermal schneller ist:

#!/usr/bin/sed -f
s/&/\&amp;/g
s/</\&lt;/g
s/>/\&gt;/g
s/"/\&quot;/g
s/'/\&apos;/g

Wo ich gerade dabei bin: Eine Lösung in Python ist nochmal
ein Drittel schneller, allerdings gehört Python nicht zum
Basissystem von FreeBSD, insofern ist es weniger portabel.

#!/usr/local/bin/python
from sys import stdin, stdout
t = stdin.read()
t = t.replace("&", "&amp;")
t = t.replace("<", "&lt;")
t = t.replace(">", "&gt;")
t = t.replace('"', "&quot;")
t = t.replace("'", "&apos;")
stdout.write(t)

(Den Geschwindigkeitsvergleich habe ich mit einer 25MB-Datei
gemacht, in der in ca. jeder fünften Zeile eine Ersetzung
gemacht werden musste.)

Gruß
   Olli

-- 
Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing b. M.
Handelsregister: Registergericht Muenchen, HRA 74606,  Geschäftsfuehrung:
secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün-
chen, HRB 125758,  Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart
FreeBSD-Dienstleistungen, -Produkte und mehr:  http://www.secnetix.de/bsd
"The last good thing written in C was
Franz Schubert's Symphony number 9."
        -- Erwin Dieterich
To Unsubscribe: send mail to majordomo(at)de.FreeBSD.org
with "unsubscribe de-bsd-questions" in the body of the message
Received on Wed 14 Jan 2009 - 08:36:18 CET

search this site