2014-07-22 19 views
28

Linie w pliku:SED: Jak UNCOMMENT linii zawierającej określony ciąg? (Edycja inline)

-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 

wypowiedzieć się powiedzmy wiersz zawierający

2001 

mogę po prostu uruchomić ten SED komendy:

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

ale teraz jak mogę wrócić?

jak w odkomentowaniu tej samej linii?

próbowałem

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

, który nie działa.

+4

'sed -i '/ 2001/s/^ # //" plik "może być? –

+1

Dlaczego używasz tej techniki? Standardową techniką byłoby użycie jednej linii w skrypcie i uczynienie numeru roku argumentem skryptu. Możesz nawet ustawić domyślnie na 2001, jeśli nie podano żadnego argumentu ('$ {1: -2001}') lub użyć zmiennej środowiskowej ('$ {DEFAULT_YEAR: -2001}') lub obu ('$ {1 : - $ {DEFAULT_YEAR: -2001}} '). –

Odpowiedz

33

Spróbuj polecenia sed,

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

dlaczego '.' usunie pierwszy znak, nawet jeśli nie jest komentarzem? –

+0

@Jidder op powiedział, że został już skomentowany. –

+2

nadal musi być odporna na błędy. ta odpowiedź wymaga poprawek, jeśli ma zostać wybrana. –

3

celu uzupełnienia @Avinash Raj's helpful answer z bardziej ogólny, POSIX rozwiązania.

  • Przełącza komentując linii pasujących do Definiowany ciąg, które muszą wystąpić jako osobne słowo gdziekolwiek na linii.
  • Znak komentarza (ciąg) jest również , który można określić pod numerem.

Należy zauważyć, że rozwiązanie jest awk -na, ponieważ solidna przenośny rozwiązanie z sed jest praktycznie niemożliwe ze względu na ograniczenia podstawowych wyrażeń regularnych POSIX”.

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:]]) i ($|[[:punct:][:space:]]) są POSIX'owych regex odpowiedniki \<, a słowo-\> granica twierdzeń znane z innych regex dialektów.
  • Whitespace po znak komentarza zostaje zachowany, ale nie przed nim.
  • Podczas dodawania znaku komentarza do linii jest on bezpośrednio dodawany bez białych znaków.
  • W ten sposób, jeśli tylko zmienisz komentarze za pomocą tego rozwiązania, wszystkie białe spacje zostaną zachowane.
  • POSIX awk nie oferuje aktualizacji w miejscu (ani nie POSIX sed, nawiasem mówiąc), stąd dane wyjściowe są najpierw przechwytywane w pliku tymczasowym, a następnie plik zastępuje oryginał po pomyślnym zakończeniu.
43

Tak, aby skomentować wiersz zawierający specyficzny łańcuch z SED, po prostu zrobić:

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

I to odkomentowaniu:

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

W twoim przypadku:

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

Opcja "g" na końcu oznacza globalną zmianę. Jeśli chcesz zmienić tylko jedną instancję wzorca, po prostu pomiń to.

+0

dodaj argument "-e" dla macOS i BSD –

+0

Aby uniknąć wielokrotnego komentowania i uwzględnienia wielu wiodących '# ', użyj następujących poleceń: ' sed -i'//s/^ # */#/g 'plik (do skomentowania) ' i ' sed -i'//s/^ # * // // g 'plik (do odkomentowania) ' –

Powiązane problemy