Sed: sostituisci un personaggio in una linea abbinata in atto?


21

In un file contenente righe come questa:

# lorem ipsum blah variable

Vorrei rimuovere #(commentare) il carattere nella stessa riga che contiene una stringa specifica, in atto. Va sedbene per questo?

Sto lottando per ottenere questo lavoro condizionale. Ho un modo "maldestro" di farlo; Posso trovare il numero di riga corrispondente con awko sede quindi utilizzare questo numero in un sedcomando separato , ma credo che ciò possa essere fatto in un modo molto migliore.

Risposte:


36

Usa la stringa che stai cercando come selettore per le linee su cui operare:

sed '/ipsum/s/#//g'

/ipsum/seleziona le righe contenenti "ipsum" e solo su queste righe vengono eseguiti i comandi che seguono. È possibile utilizzare le parentesi graffe per eseguire più comandi

/ipsum/{s/#//g;s/@/-at-/g;}

4
Sono d'accordo; questa è la risposta migliore (anche se non l'unica). Commenti: (1) 's/#//g'rimuoverà tutti i #caratteri nella riga. Se non è quello che vuoi, rimuovi il g(che sta per "globale"). (2) Per modificare un file sul posto (come richiesto nella domanda), utilizzare sed -i.
G-Man dice "Ripristina Monica" il

2
(3) Per quanto riguarda le situazioni del mondo reale, se si desidera annullare il commento di una riga, è possibile utilizzare sed -i '/ipsum/s/#[[:space:]]*//', per sbarazzarsi di eventuali spazi e schede immediatamente dopo il #. (4) Potresti anche considerare di verificare che #sia il primo carattere non vuoto nella riga. Il comando corrente eliminerebbe il #dalla riga prompt "Enter # of ipsums:".
G-Man dice "Ripristina Monica" il

1
@ G-Man - grande aggiunta! Al tuo secondo pt (spazio iniziale), che dire di: sed -i '/ipsum/s/^#[[:space:]]*//'?! ( ^indica l'inizio della linea, $per la fine della linea) - almeno in gnu sed ...
Jeremy Davis,

1
@JeremyDavis: Sì, si potrebbe ancorare le regex per l'inizio della linea con ^, ma sarebbe sbagliato. Commento spesso il codice rientrato inserendo #immediatamente il codice, quindi il #rientro. Dubito di essere l'unica persona che lo fa.
G-Man dice "Reinstate Monica" il

1
@ G-Man - ah sì, certo! Grazie, non l'avevo considerato. Così si sarebbe anche voler verificare la presenza di spazi tra ^e #, quindi qualcosa di più simile a questo: /ipsum/{/^[[:space:]]*#/s/#[[:space:]]*//}. Anche se anche allora, a seconda di dove si #trova, può comunque causare problemi (ad es. Nelle lingue che usano rientro / separazione degli spazi bianchi).
Jeremy Davis,

7
$ cat input.txt
# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
# lorem ipsum blue variable

poi:

$ sed 's|# \(.*blue.*\)|\1|' input.txt

dà:

# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
lorem ipsum blue variable

Funziona come segue:

Il sdice sedche dovrebbe sostituire quello che l'espressione regolare trova.

Lo schema è # \(.*blue.*\)il seguente: Trova un hash seguito da uno spazio. La parentesi ( \() avvia il raggruppamento. .*blue.*è la parola bluecon qualsiasi cosa prima e dopo. La parentesi successiva ( \)) chiude il raggruppamento.

Il rimpiazzo è \1un riferimento a ritroso al contenuto della prima parentesi di raggruppamento.


3

Puoi usare Vim in modalità Ex:

ex -sc '/ipsum/s/#//|x' file
  1. s sostituire

  2. x salva e chiudi


È abbastanza bello. Non lo sapevo! TBH, non sono sicuro che sia la migliore risposta a questa domanda (IMO la principale risposta sed è quella) ma è comunque molto interessante! Grazie per la pubblicazione.
Jeremy Davis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.