tutorials.de Buch-Aktion 05/2012
Like Tree2Danke
  • 1 Beitrag von deepthroat
  • 1 Beitrag von deepthroat
ERLEDIGT
NEIN
ANTWORTEN
11
ZUGRIFFE
1344
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    OnePixel Tutorials.de Gastzugang
    Hallo @All,

    ich habe ein Problem mit sed und hoffe hier auf Hilfe bzw. Lösung meines Problems

    zu meinem Probem:
    Ich möchte in der "resolv.conf" einen nameserver hinzufügen, der unter dem letzten nameserver-EIntrag stehen soll. Ich wollte also nun mit sed
    den letzten nameserver am Zeilenanfang suchen und unter dem eine Leerzeile einfügen und in einem weiteren sed Befehl den neuen nameserver eintragen.

    Der zweite Befehl funktioniert auch jedoch kann ich mit sed nicht den ersten umsetzen (den letzten nameserver am Zeilenanfang suchen und eine Leerzeile unter diesem einfügen.

    Der zweite Befehl sieht bei mir wie folgt aus:
    cat /etc/resolv.conf | sed "s/^$/nameserver 999.999.99.9/" > /etc/resolv.conf

    Die resolv.conf besitzt bei mir folgende Syntax:

    domain meineDomain.com
    nameserver 999.999.99.9
    nameserver 888.888.88.8
    nameserver 777.777.77.7
    search meineDomain.com meinedomain.net


    Die sed-Befehle sollen dann in ein sh script, welches auf verschiedenen Servern ausgeführt wird. Die Anzahl der nameserver variert. Über die Zeile kann man also leider nicht gehen.

    Könnt ihr mir helfen?
    Danke schon mal im vorraus.

    Lieben Gruß
    OnePixel
     

  2. #2
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.806
    Blog-Einträge
    5
    Hallo OnePixel,

    probier mal folgendes Shell-Skript:
    Code bash:
    1
    2
    3
    4
    5
    6
    7
    
    #!/bin/sh
     
    FILE="/etc/resolv.conf"
    ENTRY="nameserver 666.666.66.6"
     
    LINE=`sed -n '/^nameserver /=' "$FILE" | tail -n 1`
    sed -i "${LINE}a${ENTRY}" "$FILE"

    Grüße,
    Matthias
     
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  3. #3
    OnePixel Tutorials.de Gastzugang
    ERSTMAL DANKE FÜR DIE SCHNELLE ANTWORT

    habe es mal ausgeführt, jedoch mit folgender Fehlermeldung:

    Syntax: tail [+/-[n][lbc][f]] [datei]
    tail [+/-[n][l][r|f]] [datei]
    sed: Unzulässige Option -- i

    Kann damit leider nichts anfangen....

    habe selbst auch nochmal probiert:
    mit folgendem Kommando bekomm ich eine Leerzeile unter allen Zeilen, die mit nameserver beginnen. Kennst du das Metazeichen, mit dem ich sage,
    dass er nur das letzte Vorkommen von nameserver benutzen soll?

    cat /etc/resolv.conf | sed '/^nameserver/G'

    Habe gehofft das man nur noch nen .? an die richtige Stelle fixieren müsste.....

    Danke schonmal
    Lieben Gruß
    OnePixel
     

  4. #4
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.806
    Blog-Einträge
    5
    Zitat Zitat von OnePixel Beitrag anzeigen
    ERSTMAL DANKE FÜR DIE SCHNELLE ANTWORT

    habe es mal ausgeführt, jedoch mit folgender Fehlermeldung:

    Syntax: tail [+/-[n][lbc][f]] [datei]
    tail [+/-[n][l][r|f]] [datei]
    sed: Unzulässige Option -- i

    Kann damit leider nichts anfangen....
    Oh, da hab ich wohl ein paar GNU-Erweiterungen verwendet. Probier es mal so:
    Code bash:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #!/bin/sh
     
    FILE="/etc/resolv.conf"
    ENTRY="nameserver 666.666.66.6"
    TMPFILE="`tempfile`"
     
    LINE=`sed -n '/^nameserver /=' "$FILE" | tail -1`
    sed "${LINE}a${ENTRY}" "$FILE" >"$TMPFILE"
    mv "$TMPFILE" "$FILE"
    Das -i bei sed sollte dafür sorgen, dass die Datei in-place bearbeitet wird. Kann man aber auch mit cat erreichen. \edit: Quatsch. Man muss eine temporäre Datei verwenden, wie deepthroat weiter unten anmerkt. Habe das Skript mal ausgebessert.

    Zitat Zitat von OnePixel Beitrag anzeigen
    habe selbst auch nochmal probiert:
    mit folgendem Kommando bekomm ich eine Leerzeile unter allen Zeilen, die mit nameserver beginnen. Kennst du das Metazeichen, mit dem ich sage,
    dass er nur das letzte Vorkommen von nameserver benutzen soll?
    Ich bezweifle, dass das mit einem sed-Aufruf alleine funktioniert. sed arbeitet ja zeilenweise und man kann nicht feststellen, ob eine Zeile die letzte ihrer Art ist, ohne alle restlichen Zeilen durchzulaufen. Ich lasse mich da aber gerne eines besseren belehren, da ich kein Experte im Umgang mit sed bin.

    Grüße,
    Matthias
    Geändert von Matthias Reitinger (25.02.10 um 15:08 Uhr)
     
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  5. #5
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.
    Zitat Zitat von Matthias Reitinger Beitrag anzeigen
    Ich bezweifle, dass das mit einem sed-Aufruf alleine funktioniert. sed arbeitet ja zeilenweise und man kann nicht feststellen, ob eine Zeile die letzte ihrer Art ist, ohne alle restlichen Zeilen durchzulaufen. Ich lasse mich da aber gerne eines besseren belehren, da ich kein Experte im Umgang mit sed bin.
    Na, wenn das keine Herausforderung ist.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    #!/bin/sed -nf
     
    H
     
    /^nameserver /{
      s/^.*$//
      x
      s/^\n//
      p
    }
     
    ${
      i\
    nameserver blablabla
      g
      s/^\n//
      p
    }
    Gruß
    Geändert von deepthroat (25.02.10 um 15:35 Uhr) Grund: Backslash entfernt und d Befehl entfernt
    Matthias Reitinger bedankt sich. 
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  6. #6
    OnePixel Tutorials.de Gastzugang
    Hallo nochmal

    also habe das Problem jetzt gelöst.
    Meine Lösung:

    RESOLV_CONF="/etc/resolv.conf"
    AUSGABE_TAIL="`cat "${RESOLV_CONF}" | grep "nameserver" | tail -1`"

    cat ${RESOLV_CONF} | sed "/${AUSGABE_TAIL}/G" | sed "s/^$/nameserver 333.33.333.3/" > ${RESOLV_CONF}

    TADA

    EInen riesen dank an euch ! Thanks a lot
    Liebe Grüße
    OnePixel
     

  7. #7
    OnePixel Tutorials.de Gastzugang
    Und ein riesen WOW an dich deepthroat.
    Krasse Sache

    DANKE
     

  8. #8
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Zitat Zitat von OnePixel Beitrag anzeigen
    RESOLV_CONF="/etc/resolv.conf"
    AUSGABE_TAIL="`cat "${RESOLV_CONF}" | grep "nameserver" | tail -1`"

    cat ${RESOLV_CONF} | sed "/${AUSGABE_TAIL}/G" | sed "s/^$/nameserver 333.33.333.3/" > ${RESOLV_CONF}
    Hast du das getestet? Normalerweise wird bei dieser Art Umleitung zuerstmal die Datei auf 0 Byte geschrumpft bevor cat überhaupt anfängt zu lesen. In der Regel ist das reine Glückssache falls es funktioniert.

    Du mußt entweder die Datei erstmal komplett in den Speicher lesen (ist ja nicht so groß) oder temporäre Dateien verwenden.

    Was für ein Betriebssystem verwendest du denn? Welche Shell?

    Gruß

    PS: Und bitte verwende die Code-Tags für deine Codeschnipsel!
    Geändert von deepthroat (25.02.10 um 14:28 Uhr)
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  9. #9
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.806
    Blog-Einträge
    5
    Zitat Zitat von deepthroat Beitrag anzeigen
    Hi.
    Na, wenn das keine Herausforderung ist.

    […]
    Du Teufelskerl, eine Reaktion von dir hatte ich schon befürchtet/erwartet Magst du vielleicht noch das Prinzip kurz erklären?

    \edit: Der Backslash in der Zeile nameserver blablabla\ gehört aber weg, oder? Zumindest klappt es auf meinem System nur ohne.

    Grüße,
    Matthias
     
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  10. #10
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Zitat Zitat von Matthias Reitinger Beitrag anzeigen
    Du Teufelskerl,

    Zitat Zitat von Matthias Reitinger Beitrag anzeigen
    eine Reaktion von dir hatte ich schon befürchtet/erwartet Magst du vielleicht noch das Prinzip kurz erklären?
    Ich dachte das wäre selbstdokumentierender Code?!

    Die grundlegende Vorgehensweise ist folgende:

    Jede Zeile wird erstmal zum Hold-Space hinzugefügt (mit einem führenden Zeilenumbruch).

    Wenn die Zeile mit nameserver beginnt, dann wird der Pattern-Space gelöscht und mit dem Hold-Space vertauscht und es werden alle bisher gelesenen Zeilen ausgegeben (ohne den führenden Zeilenumbruch).

    Das wiederholt sich bis die Verarbeitung am Ende der Eingabe angekommen ist (die $ Adresse). Bisher wurde immer bis zum zuletzt gelesenen nameserver Eintrag schon alles ausgegeben und es ist auch kein solcher Eintrag mehr aufgetreten, also muss jetzt der neue Eintrag ausgegeben werden und dann noch der restliche Text aus dem Hold-Space (ohne führenden Zeilenumbruch).

    Man sollte das ganze evlt. doch lieber komplett in Bash schreiben.
    Zitat Zitat von Matthias Reitinger Beitrag anzeigen
    \edit: Der Backslash in der Zeile nameserver blablabla\ gehört aber weg, oder? Zumindest klappt es auf meinem System nur ohne.
    Richtig, der Backslash muss weg. Oder nach dem Backslash muss noch ein Leerzeichen folgen, welches der Highlighter hier unterschlagen hat. (irgendwie hat mich da die Formulierung der info Seiten irritiert). Außerdem fällt mir gerade auf, das der d Befehl überflüssig ist.

    Gruß
    Matthias Reitinger bedankt sich. 
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  11. #11
    OnePixel Tutorials.de Gastzugang
    Also das funktioniert super. Habe ein weiteres Script geschrieben, dass dieses Script auf Server kopiert, ausführt und anschließend wieder löscht.
    Dieses Script wird in der Bourne-Shell (sh) ausgeführt.
    Das OS ist ein Solaris x86 Serversystem. Die Anzahl der Server sind ca. 60 und es hat alles super funktioniert. Mein Code den ich hereingestellt habe ist ja auch nur ein Teil des Scriptes.

    Hier mal das komplette Script:

    {noformat}

    #!/bin/sh
    #
    ###############
    # Autor : Sebastian Kachel
    # Mail : sebastian.kachel@xxxx.com
    # Datum : 24.02.2010
    # Skriptname : edit_resolv.conf
    # Version : 1.0
    ###############

    # Abfrage ob Datei vorhanden ist und die Bearbeitung der resolv.conf
    #
    # Variablen:
    #NS_SERVER="111.11.11.1"
    NS2_SERVER="222.22.22.2"
    NS3_SERVER="333.33.33.3"
    NS3_SERVER_ALL="nameserver 333.33.33.3"
    RESOLV_CONF="/etc/resolv.conf"
    DATE="`date +"%Y%m%d"`"
    IFNS3="`grep -c "333.33.33.3" /etc/resolv.conf`"
    AUSGABE_TAIL="`cat "${RESOLV_CONF}" | grep "nameserver" | tail -1`"

    if [ -f ${RESOLV_CONF} ] ; then
    cp ${RESOLV_CONF} ${RESOLV_CONF}.$DATE
    sed s/${NS2_SERVER}/${NS3_SERVER}/g ${RESOLV_CONF}.$DATE > ${RESOLV_CONF}
    cat ${RESOLV_CONF}
    echo "..................................................................."

    if [ "${IFNS3}" -gt "0" ] ; then
    echo "${RESOLV_CONF} already done..............................."

    else
    cat /etc/resolv.conf | sed "/${AUSGABE_TAIL}/G" | sed "s/^$/nameserver 333.33.33.3/" > ${RESOLV_CONF}
    cat ${RESOLV_CONF}
    echo "${RESOLV_CONF} already done..............................."
    fi



    fi
    {noformat}


    Und das Script das Anhand einer Serverliste sich auf die Server über ssh einloggt und dann das Script (OBEN) kopiert, ausführt und wieder löscht.

    {noformat}

    #!/bin/ksh
    #
    ###############
    # Autor : Sebastian Kachel
    # Mail : sebastian.kachel@xxx.com
    # Datum : 10.02.2010
    # Skriptname : verteiler.sh
    # Version : 1.0
    ###############
    #
    #Script, dass ein Script, auf der Auswahl einer Serverliste
    #auf Server kopiert, ausführt und wieder löscht.
    #
    #Variablen:
    SERVER=$SERVER" "`cat ~/Serverlists/SOLARIS`

    [ $# -eq 1 ] && SERVER=$1

    for server in $SERVER ; do
    ping "$server" 1 > /dev/null
    ping "$server" 1 > /dev/null
    ping "$server" 1 > /dev/null

    if [ "$?" = "0" ]; then
    echo "$server"
    scp /xxx/xx/xxxxxxx/edit_resolv_conf.sh root@${server}:/var/tmp/edit_resolv_conf.sh
    ssh root@${server} "sh /var/tmp/edit_resolv_conf.sh"
    ssh root@${server} "rm /var/tmp/edit_resolv_conf.sh"
    else
    echo "...$server is dead."
    fi
    done


    {noformat}


    Aus Sicherheitsgründen sind IP und Phade durch xxx ersetzt


    Nochmls einen großen Dank an euch . Echt klasse !

    Liebe Grüße
    OnePixel
     

  12. #12
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Zitat Zitat von OnePixel Beitrag anzeigen
    Also das funktioniert super.
    Das scheint dann aber eine etwas unübliche Verhaltensweise der SunOS Bourne Shell zu sein.
    Zitat Zitat von http://snap.nlc.dcccd.edu/learn/madden/intro/common/redirect.html
    Standard Output

    There are two output redirection operators in UNIX.

    1. date > myfile

    redirects the output of a process (date) to the file specified after the metacharacter, in this case, myfile. Two significant things happen when this type of redirection is used: First, UNIX looks to see if the file specified already exists. If it does, then the next byte pointer (NBP) in the file is set to byte zero. That means the contents of the file are instantly, absolutely, totally, and irrevocably lost.

    For example, this code shows the fastest cat possible:

    cat myfile > myfile

    When the shell starts to execute this command, it first does file handling, and sees the redirection. Since the first thing it does when a file is the target of a redirection is to set the next byte pointer to byte zero, the file "myfile" suddenly becomes very, very empty. Cating an empty file is pretty quick!
    Und bitte fasse deine Codeschnipsel in [code]...[/code] Tags ein!

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

Ähnliche Themen

  1. Letztes Vorkommen im String entfernen
    Von Dustin84 im Forum PHP
    Antworten: 5
    Letzter Beitrag: 09.11.10, 00:15
  2. letztes Zeichen eines Strings auslesen
    Von supercat1510 im Forum PHP
    Antworten: 8
    Letzter Beitrag: 10.07.09, 23:29
  3. Excel: letztes Vorkommen eines Zeichens ersetzen: /aa/bb/cc --> /aa/bb cc
    Von Kryptaesthesie im Forum Office-Anwendungen
    Antworten: 6
    Letzter Beitrag: 19.10.07, 13:20
  4. Letztes Vorkommen einer Zeichenkette finden
    Von 27apricot im Forum PHP
    Antworten: 2
    Letzter Beitrag: 16.10.05, 17:03
  5. Letztes Vorkommen ersetzen ?
    Von Hatachy im Forum PHP
    Antworten: 7
    Letzter Beitrag: 16.05.04, 00:38