Bash-Skript: Zeilen auskommentieren

  • Hallo zusammen,


    ich möchte dxr3config für das kommende linvdr 0.8 vorbereiten.


    Aus diesem Grunde benötige ich eine Bash-Skript-Schnipsel, der folgendes leistet.


    Vorgabe:
    a) Datei Name inklusive Pfad
    b) Suchstring


    Ausgabe:
    In der vorgegebenen Datei wir jede Zeile, die den Suchstring enthält, auskommentiert.


    Falls jemand einen solchen Schnipsel auf seiner Festplatte hat, oder weiß wo man ihn bekommt, dann würde ich mich über einen Post freuen. :]


    Ansonsten schreibe ich ihn selber. Ich weiß jedoch nicht wie gut er dann wird und wie lange ich daran sitze. ?(


    Gruß
    Wicky

  • Moin,


    Einspruch, Euer Ehren. Die Schnipsel entfernen die Zeilen mit dem Muster bzw. ohne das Muster. Unter "auskommentieren" verstehe ich "ein '#' am Anfang der gesuchten Zeile einfügen". Also:

    Code
    sed -i "/suchmuster/s/^\(.*\)/#\1/g"  datei


    Das Suchmuster ist ein reg. Ausdruck.
    Wenn man das -i weglässt wird die Datei nicht geändert. Stattdessen wird das Ergebnis nach stdout gegeben.


    Gruss,
    Walter

    --seit 2010 kein vdr mehr in Betrieb--
    vdr 1.6.0 + eigene Patchkombination
    GNU/Linux 2.6.23.14 (Debian)
    DVB-S-Karte TT 1.6 (FF, Tuner defekt)
    DVB-S-Karte TT Budget (seit 4/09)
    DVB-T-Karte TT 1300
    DVB-T-USB-StickTerratec Cinergy T USB XE Rev. 2
    PC-Hauptplatine: MSI K8N Neo4-F, AMD 64 (seit 1/07)

    Einmal editiert, zuletzt von Walter, dg9ep ()

  • Servus Wicky,


    ein komplettes Script hab ich für dich nicht, dafür aber die nötigen Befehle.
    Wenn du die Variable "IFS" auf Newline setzt ($'\n'), kannst du mit "read $Zeile < dateiname" eine Datei zeilenweise einlesen, am besten in einer while-Schleife. Also ein Konstrukt wie "while read $Zeile < dateiname; do ... done".


    Mit Hilfe der Suchen/Ersetzen-Funktion ${Zeile/Suchmuster/Ersetzung} kannst du z.B. testen, ob das Muster in der Zeile vorkommt: "if [ -z "${Zeile/*Test*}" ]; then ... fi"


    Dann noch die Ausgabe dazu, also entweder "echo "$Zeile" >> neuedatei" oder "echo "# $Zeile" >> neuedatei".


    Beachte: Du kannst nicht ohne Weiteres in der Datei gleichzeitig lesen und schreiben.


    Natürlich ließe sich das ganze auch mit sed oder ed erreichen, nur würde ich nicht darauf bauen, da wir ja Busybox benutzen. Die Bash hingegen ist und bleibt full-featured.


    Viele Grüße, Mirko

  • ...danke euch allen.


    Die neue dxr3config Version habe ich heute Vormittag schon fast fertig bekommen. Sie wird jetzt Debian-Kompatibel werden.


    Wenn ich einen gescheiten Schnipsel zusammen habe, dann werde ich ihn hier posten. Ich werde auch eine "non-sed-Variante" testen.


    Gruß
    Wicky

  • @all


    momentan verwende ich die Zeile von "Walter, dg9ep".


    Sie funktioniert genau wie von mir erhofft. Doch leider ist die Anforderung ungenügend, denn eine Zeile sollte nur dann nochmals auskommentiert werden, wenn sie noch nicht auskommentiert ist.


    Daher eine geänderte Logik:


    Vorgabe:
    a) Datei Name inklusive Pfad
    b) Suchstring


    Ausgabe:
    In der vorgegebenen Datei wir jede Zeile, die den Suchstring enthält und nicht auskommentiert ist, auskommentiert.


    Ich werde mich jetzt selber mit der Erstellung der sed-Zeile auseinander setzen, befürchte allerdings, dass dies einiges daueren könnte. Über Hilfe wäre ich daher sehr dankbar. :]


    cooper
    die IFS Variante wäre mir eigentlich lieber. Aber sed wird auch unter linvdr funktionieren und wird vermutlich ersteinmal schneller zum Ziel führen. Leider habe ich z.Z. nur wenig Zeit und ich möchte die neue dxr3config und linvdr-dxr3.deb Version so schnell wie möglich veröffentlichen. Also wird es vermutlich eine sed Lösung werden.


    Gruß
    Wicky

  • Hallo zusammen,


    ich habe jetzt die Zeilen gefunden, die obige neue Anforderung erfüllt.


    Aber sie ist vermutlich nicht ganz effizient. So sieht sie aus:


    Code
    sed -i "/^[^#].*Suchtext/s/^\(.*\)/#\1/g"  Datei
    sed -i "/^Suchtext/s/^\(.*\)/#\1/g"  Datei


    und konkreter sieht es bei mir dann so aus:


    Code
    sed -i "/^[^#].*adv717x/s/^\(.*\)/#\1/g"  /home/wicky/test/test.txt
    sed -i "/^[^#].*bt865/s/^\(.*\)/#\1/g"  /home/wicky/test/test.txt
    sed -i "/^[^#].*em8300/s/^\(.*\)/#\1/g"  /home/wicky/test/test.txt
    
    
    sed -i "/^adv717x/s/^\(.*\)/#\1/g"  /home/wicky/test/test.txt
    sed -i "/^bt865/s/^\(.*\)/#\1/g"  /home/wicky/test/test.txt
    sed -i "/^em8300/s/^\(.*\)/#\1/g"  /home/wicky/test/test.txt


    Eine Schleife wäre im obigen konkreten Fall wohl noch nicht sinnvoll. Eventuell sollte man aber obigen Code mal zu einer function umwandeln, die Parameter annimmt, dann wäre allerdings eine for-Schleife sinnvoll.


    Über Anmerkungen und Verbesserungen wäre ich sehr dankbar.


    Gruß
    Wicky

  • Zitat

    Original von Greywolf
    Alles in einer Zeile:

    Code
    sed '/^[[:blank:]]*#/!{/^.*\(adv717x\|bt865\|em8300\)/s/\(.*\)/#\1/}'


    ...danke :D Die Zeile scheint perfekt zu funktionieren.


    Zwei Fragen an dich/an alle:


    1. Musst du, wenn du eine solche Zeile entwickelst noch lange darüber nachdenken?
    2. Mein Bash-Buch ist leider bzgl. sed viel zu kurz geraten. Kannst du ein Buch oder eine Online-Quelle nennen, die meine mangelhaften sed-Kenntnisse beheben könnten? (Es ärgert mich doch mitterweile sehr, dass ich noch ein ziemlicher sed-dumm-user bin. ?(


    Gruß
    Wicky

  • Zitat

    Original von Wicky
    ...danke :D Die Zeile scheint perfekt zu funktionieren.


    Schön :)


    Eine Optimierung fällt mir aber gerade noch auf:

    Code
    sed '/^\s*#/!{/\(adv717x\|bt865\|em8300\)/s/\(.*\)/#\1/}'


    sed kennt "\s" und das "^.*" ist überflüssig ... und mit "extended regular expressions" lassen sich noch ein paar "\" einsparen:

    Code
    sed -r '/^\s*#/!{/(adv717x|bt865|em8300)/s/(.*)/#\1/}'


    Zitat


    Zwei Fragen an dich/an alle:


    1. Musst du, wenn du eine solche Zeile entwickelst noch lange darüber nachdenken?


    Die regulären Ausdrücke gehen meist relativ schnell (wenn auch nicht sofort optimal, wie man sieht ;)), aber die sed-Syntax musste ich nachschauen und ausprobieren. sed habe ich bisher auch nur für ganz einfache Suchen & Ersetzen Aktionen verwendet. Muss ich mir aber auch mal bei Gelegenheit näher anschauen, da ist wie man sieht noch einiges an Potential drin. ;)


    Zitat


    2. Mein Bash-Buch ist leider bzgl. sed viel zu kurz geraten. Kannst du ein Buch oder eine Online-Quelle nennen, die meine mangelhaften sed-Kenntnisse beheben könnten? (Es ärgert mich doch mitterweile sehr, dass ich noch ein ziemlicher sed-dumm-user bin. ?(


    Hast Du die Doku zu sed installiert? "man sed" haut einem nur die ganzen Parameter um die Ohren, aber über "info sed" bekommt man auch mal ein paar Beispiele.

  • ... mit Hinblick auf die Verfügbarkeit empfehle ich nach wie vor, Bash-Builtins zu benuzen, bevor du noch mehr Arbeit in Sed steckst. Alternativ kannst du Perl benutzen, so lange VDR-Admin in LinVDR enthalten ist, wird auch stets Perl dabei sein.


    Die String-Verarbeitung der Bash 2.x ist ähnlich einfach wie die von Sed, und für diese Anwendung völlig ausreichend.


    Viele Grüße, Mirko

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!