2017-03-29 1 views
1

Ich habe das folgende Skript:Bash-Skript: Ersetzen Sie eine Zeile in einer Datei

#!/bin/bash 

LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1" 
NEW_LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline" 

#sed -i "/${LINE}/c ${NEW_LINE}" grub.cfg 

LINE1="insmod lvm" 
NEW_LINE1="insmod lvm x" 

sed -i "/${LINE1}/c ${NEW_LINE1}" grub.cfg 

Kann mir jemand sagen, warum die kommentierte sed funktioniert nicht (Fehler: sed: -e expression #1, char 10: extra characters after command), aber die uncommented man tut, wenn nur die Saiten sind anders?

Antwort

1

Da Schrägstriche in der Linie sind, dass Sie suchen, müssen Sie ein anderes Zeichen verwenden, um die Grenzen des Befehls s/// zu markieren. Zum Beispiel, Sie haben keine % Symbole in den Saiten, so:

LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1" 
NEW_LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline" 

sed -i "s%.*${LINE}.*%${NEW_LINE}%" grub.cfg 

Oder den Änderungsbefehl zu halten, müssen Sie einen anderen Charakter im Spiel verwenden - Sie verwenden, um einen umgekehrten Schrägstrich vor ihm um anzuzeigen, dass du das machst.

LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1" 
NEW_LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline" 

sed -i "\%${LINE}%c ${NEW_LINE}" grub.cfg 

Die POSIX-Spezifikation für sed sagt:

The sed utility shall support the BREs described in XBD Basic Regular Expressions, with the following additions:

  • In a context address, the construction " \cBREc ", where c is any character other than <backslash> or <newline> , shall be identical to " /BRE/ ". If the character designated by c appears following a <backslash> , then it shall be considered to be that literal character, which shall not terminate the BRE. For example, in the context address " \xabc\xdefx ", the second x stands for itself, so that the BRE is " abcxdef ".

und:

[2addr]s/BRE/replacement/flags
Substitute the replacement string for instances of the BRE in the pattern space. Any character other than <backslash> or <newline> can be used instead of a <slash> to delimit the BRE and the replacement. Within the BRE and the replacement, the BRE delimiter itself can be used as a literal character if it is preceded by a <backslash> .

+0

Beachten Sie auch, dass der 'c' Befehl mit den Daten in derselben Zeile eine GNU' sed' Erweiterung ist und die '-i' Option ohne Suffix ebenfalls eine GNU' sed' Erweiterung. BSD 'sed' (zB auf macOS) unterstützt' -i', benötigt aber eine Erweiterung; Um eine Null-Erweiterung für das Backup anzugeben, verwenden Sie '-i ''' (beachten Sie, dass das leere Argument separat sein muss). Die tragbare Backup-Notation ist "-i.bak" ohne Leerzeichen zwischen dem "-i" und dem Suffix; das funktioniert mit GNU- und BSD-Varianten. –

+0

Hallo Jonathan, danke für deine Hilfe. Für mich geht das. – maimun4itu

0

Die unkommentierte Zeile funktioniert nicht, da das Trennzeichen, das Ihr sed Ausdruck verwendet, in der Sache erscheint, die Sie abgleichen und ersetzen.

LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1" 
NEW_LINE="linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline" 

sed -i "/${LINE}/c ${NEW_LINE}" grub.cfg 

Ihr sed Ausdruck wird lösen zu:

/linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1/c linux /disk0/vmlinuz rw root=/dev/mapper/VolGroup1-disk0_root console=tty0 clock=pit aacraid.msi=1 elevator=deadline 

Wie Sie sehen können, diese in mehreren Operationen im Ausdruck führt als sed erwartet, damit Ihre Fehlermeldung extra characters after command.

Wenn Sie Ihren Begrenzer auf einen anderen Charakter ändern sollte es funktionieren:

sed -i "\:${LINE}:c ${NEW_LINE}" grub.cfg 

Sie auch den s Befehl verwenden könnte - versuchen:

sed -i "s:${LINE}:c ${NEW_LINE}:g" grub.cfg 
+0

Hallo ConMan, vielen Dank für Ihre Antwort. Der Grund, warum es nicht funktioniert, ist richtig, aber scheint meine Version von sed nicht neu genug für die vorgeschlagene Lösung. Aber danke für deine Wiederholung sowieso. Es hat mir sehr geholfen. – maimun4itu

+0

@ maimun4itu: Welche Version von 'sed' verwendest du (' sed --version')? Das hat sich in letzter Zeit nicht geändert (in den letzten 10 Jahren oder mehr), also wird es überraschen, wenn es die Version ist, die das Problem darstellt. Es ist wahrscheinlicher, Probleme mit Ihrer Transkription der vorgeschlagenen Lösungen zu haben. –

Verwandte Themen