Ho un file come di seguito:
line1
line2
line3
E voglio ottenere:
prefixline1
prefixline2
prefixline3
Potrei scrivere una sceneggiatura di Ruby, ma è meglio se non ne ho bisogno.
prefixconterrà /. È un percorso, /opt/workdir/per esempio.
Ho un file come di seguito:
line1
line2
line3
E voglio ottenere:
prefixline1
prefixline2
prefixline3
Potrei scrivere una sceneggiatura di Ruby, ma è meglio se non ne ho bisogno.
prefixconterrà /. È un percorso, /opt/workdir/per esempio.
Risposte:
# If you want to edit the file in-place
sed -i -e 's/^/prefix/' file
# If you want to create a new file
sed -e 's/^/prefix/' file > file.new
Se prefixcontiene /, puoi usare qualsiasi altro personaggio non presente prefixo sfuggire a /, così il sedcomando diventa
's#^#/opt/workdir#'
# or
's/^/\/opt\/workdir/'
sedin una pipeline, ad es foo | sed -e 's/^/x /' | bar.
sed -e '2,$s/^/prefix/'.
/like \/(in stringhe tra virgolette singole) o \\/(in stringhe tra virgolette doppie)
sed -e 's/$/postfix/' filese si desidera aggiungere una stringa alla fine di ogni riga.
awk '$0="prefix"$0' file > new_file
Con Perl (sostituzione sul posto):
perl -pi 's/^/prefix/' file
prtinf "$VARIABLE\n" | awk '$0="prefix"$0'
awksegnala awk: out of memory in readrec 1 source line number 1, ma la soluzione viene sedcompletata correttamente.
Puoi usare Vim in modalità Ex:
ex -sc '%s/^/prefix/|x' file
% seleziona tutte le righe
s sostituire
x salva e chiudi
:%s/^/prefix/, poiché questa strategia finisce per essere utile in molte situazioni
Se hai Perl:
perl -pe 's/^/PREFIX/' input.file
Usando la shell:
#!/bin/bash
prefix="something"
file="file"
while read -r line
do
echo "${prefix}$line"
done <$file > newfile
mv newfile $file
Ecco una soluzione oneliner altamente leggibile usando il tscomando di moreutils
$ cat file | ts prefix | tr -d ' '
E come viene derivato passo dopo passo:
# Step 0. create the file
$ cat file
line1
line2
line3
# Step 1. add prefix to the beginning of each line
$ cat file | ts prefix
prefix line1
prefix line2
prefix line3
# Step 2. remove spaces in the middle
$ cat file | ts prefix | tr -d ' '
prefixline1
prefixline2
prefixline3
Anche se non credo che Pierr avesse questa preoccupazione, avevo bisogno di una soluzione che non ritardasse l'output della "coda" di un file dal vivo, poiché volevo monitorare simultaneamente più registri di allerta, anteponendo a ciascuna riga il nome del rispettivo registro .
Sfortunatamente, sed, cut, ecc. Hanno introdotto troppi buffering e mi hanno impedito di vedere le linee più attuali. Il suggerimento di Steven Penny di usare l' -sopzione di nlera intrigante e i test hanno dimostrato che non introduceva il buffering indesiderato che mi riguardava.
Ci sono stati un paio di problemi con l'uso nl, tuttavia, legati al desiderio di eliminare i numeri di riga indesiderati (anche se non ti interessa l'estetica di esso, potrebbero esserci casi in cui l'uso delle colonne extra sarebbe indesiderabile). Innanzitutto, l'uso di "cut" per eliminare i numeri reintroduce il problema di buffering, quindi si rovina la soluzione. In secondo luogo, l'uso di "-w1" non aiuta, dal momento che questo NON limita il numero di riga a una singola colonna, ma si allarga appena sono necessarie più cifre.
Non è carino se vuoi catturarlo altrove, ma dato che è esattamente quello che non avevo bisogno di fare (tutto era già stato scritto per registrare i file, volevo solo guardarne diversi contemporaneamente in tempo reale), il migliore modo per perdere i numeri di riga e avere solo il mio prefisso era quello di iniziare il -s stringa con un ritorno a capo (CR o ^ M o Ctrl-M). Quindi per esempio:
#!/bin/ksh
# Monitor the widget, framas, and dweezil
# log files until the operator hits <enter>
# to end monitoring.
PGRP=$$
for LOGFILE in widget framas dweezil
do
(
tail -f $LOGFILE 2>&1 |
nl -s"^M${LOGFILE}> "
) &
sleep 1
done
read KILLEM
kill -- -${PGRP}
-uopzione per sed per evitare il buffering.
Utilizzando ed:
ed infile <<'EOE'
,s/^/prefix/
wq
EOE
Questo sostituisce, per ogni riga ( ,), l'inizio della riga ( ^) con prefix.wqsalva ed esce.
Se la stringa di sostituzione contiene una barra, possiamo invece utilizzare un delimitatore diverso per s:
ed infile <<'EOE'
,s#^#/opt/workdir/#
wq
EOE
Ho citato il delimitatore here-doc EOE("end of ed") per impedire l'espansione dei parametri. In questo esempio, funzionerebbe anche senza virgolette, ma è buona norma prevenire sorprese se mai ne hai uno $nello script.
È inoltre possibile ottenere ciò utilizzando la tecnica di backreference
sed -i.bak 's/\(.*\)/prefix\1/' foo.txt
Puoi anche usare con awk in questo modo
awk '{print "prefix"$0}' foo.txt > tmp && mv tmp foo.txt
Ecco un esempio completo usando il sed approccio da questa risposta :
$ cat /path/to/some/file | prefix_lines "WOW: "
WOW: some text
WOW: another line
WOW: more text
function show_help()
{
IT=$(CAT <<EOF
Usage: PREFIX {FILE}
e.g.
cat /path/to/file | prefix_lines "WOW: "
WOW: some text
WOW: another line
WOW: more text
)
echo "$IT"
exit
}
# Require a prefix
if [ -z "$1" ]
then
show_help
fi
# Check if input is from stdin or a file
FILE=$2
if [ -z "$2" ]
then
# If no stdin exists
if [ -t 0 ]; then
show_help
fi
FILE=/dev/stdin
fi
# Now prefix the output
PREFIX=$1
sed -e "s/^/$PREFIX/" $FILE
PREFIXcontiene caratteri speciali per sed come una barra.
prefix_lines \*
Per le persone su sistemi BSD / OSX c'è un'utilità chiamata lam, abbreviazione di laminato. lam -s prefix filefarà quello che vuoi. Lo uso nelle condutture, ad esempio:
find -type f -exec lam -s "{}: " "{}" \; | fzf
... che troverà tutti i file, eseguirli su ciascuno di essi, dando a ciascun file un prefisso del proprio nome file. (E pompare l'uscita su fzf per la ricerca.)
sedcompiti leggeri come questo. Se si conosce "prefisso", è molto facile scegliere un carattere non da "prefisso".