2014-07-22 10 views
28

Die Zeilen in der Datei:SED: Wie entgegnet man eine Zeile, die eine bestimmte Zeichenfolge enthält? (Inline-Editing)

-A INPUT -m state --state NEW -m tcp -p tcp --dport 2000 -j ACCEPT 
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2001 -j ACCEPT 
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2002 -j ACCEPT 

auszukommen sie die Linie sagt, dass

2001 

enthält ich einfach diesen SED-Befehl ausführen kann:

sed -i '/ 2001 /s/^/#/' file 

aber jetzt, wie mache ich zurück?

wie in Kommentar die gleiche Zeile?

ich versuchte

sed -i '/ 2001 /s/^//' file 

, das nicht funktioniert.

+4

'sed -i '/ 2001/s/^ # //' Datei 'kann sein? –

+1

Warum verwenden Sie diese Technik? Die Standardtechnik wäre, eine Zeile im Skript zu verwenden und die Jahreszahl als Argument für das Skript zu verwenden. Sie könnten beispielsweise sagen, wenn kein Argument vorhanden ist ('$ {1: -2001}') oder verwenden Sie eine Umgebungsvariable ('$ {DEFAULT_YEAR: -2001}') oder beides ('$ {1 : - $ {DEFAULT_YEAR: -2001}} '). –

Antwort

33

Versuchen Sie, diesen sed Befehl,

sed -i '/^#.* 2001 /s/^#//' file 
+2

Warum '.' wird das erste Zeichen entfernen, auch wenn es kein Kommentar ist? –

+0

@Jidder op sagte, dass es bereits kommentiert wurde. –

+2

muss noch ausfallsicher sein. Diese Antwort muss korrigiert werden, wenn sie ausgewählt werden soll. –

3

@Avinash Raj's helpful answer mit einer allgemeineren, POSIX-kompatible Lösung zu ergänzen.

  • Schaltet von Linien kommentieren, die eine angebbaren Zeichenfolge übereinstimmen die als separates Wort überall auf der Linie auftreten müssen.
  • Die Kommentarzeichen (Zeichenfolge) ist auch vorgebbar.

Beachten Sie, dass die Lösung awk ist -basierte, weil eine robuste portable Lösung mit sed praktisch unmöglich ist, aufgrund der Beschränkungen von POSIX‘Grund reguläre Ausdrücke.

awk -v commentId='#' -v word='2001' ' 
    $0 ~ "(^|[[:punct:][:space:]])" word "($|[[:punct:][:space:]])" { 
    if (match($0, "^[[:space:]]*" commentId)) 
     $0 = substr($0, RSTART + RLENGTH) 
    else 
     $0 = commentId $0 
    } 
    { print } 
    ' file > tmpfile.$$ && mv tmpfile.$$ file 
  • (^|[[:punct:][:space:]]) und ($|[[:punct:][:space:]]) sind die POSIX von anderen regex Dialekten regex Äquivalente der \< und \> Wortgrenze Assertionen bekannt verlängert.
  • Whitespace nach der Kommentar Char ist erhalten, aber nicht davor.
  • Wenn Sie das Kommentar-Zeichen einer Zeile voranstellen, wird es direkt vorangestellt, ohne Leerzeichen.
  • Wenn Sie also nur Kommentare mit diese Lösung umschalten, werden alle Leerzeichen beibehalten.
  • POSIX awk bietet keine direkte Aktualisierung (POSIX sed, übrigens), daher wird die Ausgabe zuerst in einer temporären Datei erfasst und diese Datei ersetzt dann das Original bei Erfolg.
43

Ja, Kommentarzeile mit sed bestimmte Zeichenfolge enthält, tun einfach:

sed -i '/<pattern>/s/^/#/g' file 

Und um den Kommentar aufzuheben:

sed -i '/<pattern>/s/^#//g' file 

In Ihrem Fall:

sed -i '/2001/s/^/#/g' file (to comment out) 
sed -i '/2001/s/^#//g' file (to uncomment) 

Option "g" am Ende bedeutet globalen Wandel. Wenn Sie nur eine einzelne Instanz eines Musters ändern möchten, überspringen Sie dies einfach.

+0

fügen Sie das '-e'-Argument für macOS und BSD hinzu. –

+0

Um zu vermeiden, mehrfach zu kommentieren und mehrere führende' # 'zu berücksichtigen, verwenden Sie die folgenden Befehle: ' sed -i '/ /s/^ # */#/g 'Datei (auskommentieren) ' und ' sed -i'//s/^ # * // g 'Datei (zum Auskommentieren) ' –

Verwandte Themen