Risposte:
Puoi usare sed
:
sed -i 's/^/your_string /' your_file
Grazie ai commenti di Stephane e Marco, nota che l' -i
opzione non è POSIX. Un modo POSIX per fare quanto sopra sarebbe
sed 's/^/your_string /' your_file > tmp_copy && mv tmp_copy your_file
oppure perl
:
perl -pi -e 's/^/your_string /' your_file
Spiegazione
Entrambi i comandi eseguono una sostituzione regex, sostituendo l'inizio di una riga ( ^
) con la stringa desiderata. L' -i
opzione in entrambi i comandi assicura che il file sia modificato in posizione (ovvero le modifiche si riflettono nel file anziché stampate su stdout).
sed
dovrebbe essere disponibile su qualsiasi sistema operativo compatibile con POSIX e perl
dovrebbe essere disponibile sulla maggior parte dei moderni Unices, tranne forse per quelli che hanno attraversato lo sforzo di rimuoverlo.
sed -i
non è POSIX. È GNU. FreeBSD sed
ha un'opzione simile, ma è necessario sed -i ''
lì.
-i
crea una copia temporanea (ecco perché ho detto che le modifiche si riflettono nel file originale); Volevo dire che ottieni la stessa semantica della sostituzione sul posto. Verifica che la risposta aggiornata sia conforme a POSIX.
$$
(l'ID di processo della shell corrente) come parte di un nome di file temporaneo; evita ogni volta lo sforzo di pensare a un nome univoco garantito:command filename > filename.$$ && mv filename.$$ filename
:|paste -d'foo ' - - - - input > output
(sto scherzando, anche se probabilmente troverai la più veloce di tutte le soluzioni pubblicate qui: -b).
Il modo canonico è:
sed 's/^/foo /' < input > output
Tuttavia, non si adatta facilmente alle stringhe arbitrarie. Per esempio,
sed "s/^/$var /"
Funziona solo se $var
non contiene, &
, \
, /
né caratteri di nuova riga.
A tal proposito,
export var
awk '{print ENVIRON["var"], $0}'
o
perl -pe '$_="$ENV{var} $_"'
funzionerebbe meglio.
awk
Presento una soluzione usando anteporre la stringa "pippo".
awk '{ print "foo", $0; }' input > output
awk
è multipiattaforma e disponibile su qualsiasi sistema POSIX. Non esegue modifiche sul posto. Se desideri modificare un file senza crearne un secondo, dovrai utilizzare un file temporaneo. Vedi la sed
risposta di Joseph , mostra la sintassi. Un altro trucco consiste nell'utilizzare la seguente sintassi, che in pratica sta creando un file temporaneo con lo stesso nome del file originale.
{ rm file; awk '{ print "foo", $0 }' > file; } < file
reducto# wc -l foo
`914 foo` reducto# { rm foo ; awk '{ print "prepend" , $0 }' > foo } < foo
>
Questo non sembra funzionare. Ci stavo provando perché il reindirizzamento all'originale mi rendeva nervoso, ma non sarebbe nemmeno iniziato.
Puoi evitare i problemi della modifica sul posto con gli strumenti di streaming utilizzando uno strumento che normalmente esegue la modifica sul posto: un editor!
ex sample.txt -c "%s/^/foo /" -c wq
C'è un ulteriore vantaggio che i comandi sono facili e ovvi per chiunque sia esperto nell'unico vero editor.
Puoi usare perl
per fare questo:
$ perl -pi -e 's/^/mystring /' afile.txt
Crea un file di esempio.
$ seq 5 > afile.txt
$ cat afile.txt
1
2
3
4
5
Esegui il comando sopra:
$ perl -pi -e 's/^/mystring /' afile.txt
$ cat afile.txt
mystring 1
mystring 2
mystring 3
mystring 4
mystring 5
sed
, ho mostrato come usare il Perl .... non cercare una guerra santa sull'argomento.
Semplicemente usando Bash
while IFS= read -r line; do echo "foo" "${line}" ; done < input > Output
Usando Python
python -c "import sys; print 'foo '.join([ l for l in sys.stdin.readlines() ])" < input > Output
Se si desidera modificare sul posto
import fileinput
import sys
for line in fileinput.input(['inputfile'], inplace=True):
sys.stdout.write('foo {l}'.format(l=line))
awk
su file molto piccoli. Il comportamento varia tra le implementazioni dell'eco e rimuove gli spazi vuoti iniziali e finali e elabora le barre rovesciate in modo speciale.
prefix () { while IFS= read -r REPLY; do printf "%s%s\n" "$1" "$REPLY"; done; }
dovrebbe essere più corretto.
{}
? Penso che @Matt ti stesse suggerendo di trasformarlo in una funzione con nome, a che serve {}
senza un nome di funzione?
Oppure puoi fare quanto segue:
vi filename.txt
Esc(per assicurarti di essere in NORMAL
modalità), quindi inserisci il seguente comando:
:1,$ s/^/mystring
1,$
semplicemente %
. Questo rende il comando :%s/^/string/
.
-i
opzione non modifica il file in posizione. Crea un nuovo file e sovrascrive quello originale al termine (prova: l'inode cambia). Non ci sono molti strumenti che eseguono modifiche sul posto, il che è un'operazione pericolosa. Inoltre, poiché menzioni POSIX, lo-i
switch non è obbligatorio per un POSIX compatibilesed
, è una caratteristica di alcune implementazioni particolari.