In Bash, come aggiungo una stringa dopo ogni riga in un file?


112

Come aggiungo una stringa dopo ogni riga in un file usando bash? Può essere fatto usando il comando sed, se sì come?

Risposte:


188

Se si sedconsente la modifica sul posto tramite il -iparametro:

sed -e 's/$/string after each line/' -i filename

In caso contrario, devi creare un file temporaneo:

typeset TMP_FILE=$( mktemp )

touch "${TMP_FILE}"
cp -p filename "${TMP_FILE}"
sed -e 's/$/string after each line/' "${TMP_FILE}" > filename

Perché hai touchil file temporaneo? E renderei il sedcomando condizionato al successo cpdell'originale o potrebbe essere perso.
In pausa fino a nuovo avviso.

Ho toccato il file per prenotare rapidamente il nome temporaneo. Potrebbe non essere necessario. Penso che tu abbia ragione a condizionare il comando sed al successo del cp. Perché non modificare il codice per apportare quella correzione. Non mi dispiacerà un po '! Tuo Tom
Tom DeGisi

Che ne dici di aggiungere una stringa prima di una riga?
Oxwivi

10
@Oxwivi: sed -e 's/^/string after each line/' -i filename $ significa fine riga. ^ significa l'inizio della riga.
Tom DeGisi

Se sto collegando in sed, sed 's/^/string after each line/'fa quello che mi aspetterei (antepone a ogni riga) ma sed 's/^/string after each line/'non lo fa (sostituisce l'intera riga con la mia stringa di aggiunta). Cosa succede? Qualche idea @TomDeGisi?
philadams

17

Preferisco usare awk. Se c'è una sola colonna, usa $0, altrimenti sostituiscila con l'ultima colonna.

Senso unico,

awk '{print $0, "string to append after each line"}' file > new_file

o questo,

awk '$0=$0"string to append after each line"' file > new_file

1
Inoltre, per aggiungere i numeri di riga (come nel mio caso), è possibile utilizzare la NRvariabile:awk '{print $0, NR}'
andrybak,

2
@optimus ho provato il tuo metodo, ma ottenendo uno spazio extra tra loro, qualche idea su come rimuoverli?
Adil Saju

@AdilSaju ha sed 's/ //g'funzionato per le mie esigenze, ma rimuoverà lo spazio in ogni riga, questa è l'opzione gper e ovunque in una riga.
Eklavyaa

@AdilSaju per favore aggiungi i dettagli. Meglio fare una nuova domanda.
Optimus Prime

@AdilSaju awk Rimuovi mi , piace {print $0"string to append after each line"}.
Culip

8

Se ce l'hai, l' utilità lam (laminato) può farlo, ad esempio:

$ lam filename -s "string after each line"

4
  1. Shell POSIX puro e sponge:

    suffix=foobar
    while read l ; do printf '%s\n' "$l" "${suffix}" ; done < file | 
    sponge file
  2. xargse printf:

    suffix=foobar
    xargs -L 1 printf "%s${suffix}\n" < file | sponge file
  3. Utilizzando join:

    suffix=foobar
    join file file -e "${suffix}" -o 1.1,2.99999 | sponge file
  4. Strumenti Shell utilizzando paste, yes, head e wc:

    suffix=foobar
    paste file <(yes "${suffix}" | head -$(wc -l < file) ) | sponge file

    Nota che pasteinserisce un carattere di tabulazione prima $suffix.

Ovviamente spongepuò essere sostituito con un file temporaneo, in seguito mvsul nome del file originale, come con altre risposte ...


1
Nessuno di questi è preferibile sed, a meno che le risorse non siano molto limitate.
agc

Mi piace la soluzione non sed. sednon è necessario per un lavoro così semplice.
Bruce

1

Io preferisco echo. usando pure bash:

cat file | while read line; do echo ${line}$string; done

-9

Sed è un po 'brutto, potresti farlo elegantemente così:

hendry@i7 tmp$ cat foo 
bar
candy
car
hendry@i7 tmp$ for i in `cat foo`; do echo ${i}bar; done
barbar
candybar
carbar

2
Non riesce per i file con più righe del limite massimo di argomenti della shell. Prova: cat foo | mentre leggi un; fare echo $ {a} bar; fatto o qualcosa del genere invece; è un sostituto adatto per nella maggior parte dei casi.
alex

1
Non riesce anche per le linee con spazi al loro interno.
In pausa fino a nuovo avviso.

1
Ehm, no, non delude Dennis. limite massimo di argomenti di shell? Crikey, ti stai comportando male.
hendry

Sì: $ cat foo foo bar baz alex @ armitage: ~ $ for i in cat foo; echo $ {i} bar; fatto foobar barbar bazbar ma dopo alcuni test, potrei sbagliarmi sul mio ragionamento, ma Dennis ha ragione
alex

3
@hendry Sì, questo fallisce per le righe con spazi, ad esempio echo "foo bar" | (for i in `cat`; do echo ${i}bar; done)che stampa 2 righe anche se l'input è 1 riga foo bar(e catleggere dallo stdin invece che da un file non fa differenza per questo).
hyde
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.