Aggiungi del testo alla fine di ogni riga


90

Sono sulla riga di comando di Linux e ho un file con

127.0.0.1
128.0.0.0
121.121.33.111

Voglio

127.0.0.1:80
128.0.0.0:80
121.121.33.111:80

Ricordo che i miei colleghi usavano sed per questo, ma dopo aver letto il manuale di sed non è ancora chiaro come farlo sulla riga di comando?


2
Ottima domanda e mi piace come l'hai inquadrata.
Anthony Rutledge,

Risposte:


139

Potresti provare a usare qualcosa come:

sed -n 's/$/:80/' ips.txt > new-ips.txt

A condizione che il formato del file sia esattamente come descritto nella domanda.

Il s///comando di sostituzione trova ( trova ) la fine di ogni riga nel file (usando il $carattere) e poi aggiunge ( sostituisce ) il :80alla fine di ogni riga. Il ips.txtfile è il file di input ... ed new-ips.txtè il file appena creato ( il risultato finale delle modifiche ) .


Inoltre, se hai un elenco di numeri IP a cui capita di avere già allegati numeri di porta, (come notato da Vlad e dato da aragaer ,) potresti provare a usare qualcosa come:

sed '/:[0-9]*$/ ! s/$/:80/' ips.txt > new-ips.txt

Quindi, ad esempio, se il tuo file di input è simile a questo (nota il :80) :

127.0.0.1
128.0.0.0:80
121.121.33.111

Il risultato finale sarebbe simile a questo:

127.0.0.1:80
128.0.0.0:80
121.121.33.111:80

@Vlad Sì; ma secondo l'input dell'esempio fornito dagli OP ... non dovrebbero esserci numeri di porta nell'elenco degli IP. :) Anche se ci fossero ... l'OP potrebbe semplicemente eseguire un altro sed in s///anticipo per estrarre qualsiasi numero di porta alla fine di ogni riga.
summea

1
Ok, solo chiarimento ... Forse dovrebbe esserci una condizione per escludere le linee in cui esiste già una porta.
Vlad

3
sed '/:[0-9]*$/ ! s/$/:80/'
aragaer

3
Aggiungilo alla tua risposta. Il suggerimento per escludere le linee con le porte è già qui nei commenti, ho appena scritto il comando esatto.
aragaer

2
Se il file ha terminatori CRLF, :80verrà aggiunto all'inizio della riga successiva. Utilizzare prima dos2unixsul file, se necessario.
djnz0feh

13

Versione concisa del comando sed :

sed -i s/$/:80/ file.txt

Spiegazione:

  • sed s tream ed itor
    • -i i n-place (modifica il file sul posto)
    • s s Comando ubstitution
    • /replacement_from_reg_exp/replacement_to_text/ dichiarazione
    • $corrisponde alla fine della riga ( replacement_from_reg_exp )
    • :80testo che vuoi aggiungere alla fine di ogni riga ( replacement_to_text )
  • file.txt il nome del file


12

Se desideri aggiungere del testo alla fine di ogni riga sul posto (nello stesso file), puoi utilizzare il -iparametro, ad esempio:

sed -i'.bak' 's/$/:80/' foo.txt

Tuttavia l' -iopzione è un'estensione Unix non standard e potrebbe non essere disponibile su tutti i sistemi operativi.

Quindi puoi considerare di usare ex(che è equivalente a vi -e/ vim -e):

ex +"%s/$/:80/g" -cwq foo.txt

che si aggiungerà :80a ogni riga, ma a volte può aggiungerla a righe vuote.

Quindi il metodo migliore è controllare se la riga contiene effettivamente un numero e quindi aggiungerlo, ad esempio:

ex  +"g/[0-9]/s/$/:80/g" -cwq foo.txt

Se il file ha un formato più complesso, considera l'utilizzo di una regex appropriata invece di [0-9].


0

Utilizzando un editor di testo, verifica la presenza di ^M(control-M o ritorno a capo) alla fine di ogni riga. Dovrai prima rimuoverli, quindi aggiungere il testo aggiuntivo alla fine della riga.

sed -i 's|^M||g' ips.txt
sed -i 's|$|:80|g' ips.txt

0
  1. È anche possibile ottenere questo risultato utilizzando la tecnica del backreference

    sed -i.bak 's/\(.*\)/\1:80/' foo.txt
    
  2. Puoi anche usarlo con awk in questo modo

    awk '{print $0":80"}' foo.txt > tmp && mv tmp foo.txt
    

-1

sed -i 's / $ /, / g' foo.txt

Lo faccio abbastanza spesso per aggiungere una virgola alla fine di un output in modo da poterlo copiare e incollare facilmente in un array Python (o nella tua lingua preferita)

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.