Come inserire un testo all’inizio di un file?

Finora sono stato in grado di trovare come aggiungere una riga all’inizio di un file, ma non è esattamente quello che voglio. Lo mostrerò su un esempio

Contenuto del file

some text at the beginning 

Risultato

  some text at the beginning 

È simile ma non voglio creare alcuna nuova riga con esso …

Mi piacerebbe farlo con sed se ansible.

sed può operare su un indirizzo:

 $ sed -i '1s/^/ /' file 

Che cosa è questo magico 1s che vedi su ogni risposta qui? Indirizzamento di linea! .

Vuoi aggiungere nelle prime 10 righe?

 $ sed -i '1,10s/^/ /' file 

Oppure puoi usare Command Grouping :

 $ { echo -n ' '; cat file; } >file.new $ mv file{.new,} 

Se il file è solo una riga, puoi usare:

 sed 's/^/insert this /' oldfile > newfile 

Se è più di una riga. uno di:

 sed '1s/^/insert this /' oldfile > newfile sed '1,1s/^/insert this /' oldfile > newfile 

Ho incluso quest’ultimo in modo che tu sappia come fare gamme di linee. Entrambi questi “sostituiscono” il marcatore della linea di partenza sulle loro linee interessate con il testo che vuoi inserire. Puoi anche (assumendo che il tuo sed sia abbastanza moderno) usa:

 sed -i 'whatever command you choose' filename 

per apportare modifiche sul posto.

Se si desidera aggiungere una riga all’inizio di un file, è necessario aggiungere \n alla fine della stringa nella soluzione migliore sopra.

La soluzione migliore aggiungerà la stringa, ma con la stringa non aggiungerà una riga alla fine di un file.

 sed -i '1s/^/your text\n/' file 

Puoi usare cat -

 printf '%s' "some text at the beginning" | cat - filename 

Per inserire solo una nuova riga:

 sed '1i\\' 

Nota che su OS X, il file sed -i file fallisce. Tuttavia, se si fornisce un’estensione di backup, sed -i old file , il file viene modificato sul posto mentre viene creato file.old . Puoi quindi eliminare file.old nel tuo script.

Salve con ritorno a capo:

 sed -i '1s/^/your text\n/' file 

PROBLEMA: tagga un file, nella parte superiore del file, con il nome base della directory superiore.

Ie, per

 /mnt/Vancouver/Programming/file1 

etichettare la parte superiore di file1 con Programming .

SOLUZIONE 1 – file non vuoti:

 bn=${PWD##*/} ## bn: basename sed -i '1s/^/'"$bn"'\n/'  

1s posiziona il testo alla riga 1 del file.

SOLUZIONE 2 – file vuoti o non vuoti:

Il comando sed , sopra, non riesce sui file vuoti. Ecco una soluzione, basata su https://superuser.com/questions/246837/how-do-i-add-text-to-the-beginning-of-a-file-in-bash/246841#246841

 printf "${PWD##*/}\n" | cat -  > temp && mv -f temp  

Si noti che è richiesto il comando - nel comando cat (legge input standard: consultare man cat per ulteriori informazioni). Qui, credo, è necessario prendere l’output dell’istruzione printf (su STDIN) e cat e il file su temp … Vedi anche la spiegazione in fondo a http://www.linfo.org/cat .html .

Ho anche aggiunto -f al comando mv , per evitare di chiedere conferma per sovrascrivere i file.

Per recurse su una directory:

 for file in *; do printf "${PWD##*/}\n" | cat - $file > temp && mv -f temp $file; done 

Nota anche che questo si romperà su percorsi con spazi; ci sono soluzioni, altrove (ad esempio il globbing dei file o find . -type f ... -type solutions) per quelli.

ADDENDUM: Re: il mio ultimo commento, questo script ti permetterà di ricorrere alle directory con gli spazi nei percorsi:

 #!/bin/bash ## https://stackoverflow.com/questions/4638874/how-to-loop-through-a-directory-recursively-to-delete-files-with-certain-extensi ## To allow spaces in filenames, ## at the top of the script include: IFS=$'\n'; set -f ## at the end of the script include: unset IFS; set +f IFS=$'\n'; set -f # ---------------------------------------------------------------------------- # SET PATHS: IN="/mnt/Vancouver/Programming/data/claws-test/corpus test/" # https://superuser.com/questions/716001/how-can-i-get-files-with-numeric-names-using-ls-command # FILES=$(find $IN -type f -regex ".*/[0-9]*") ## recursive; numeric filenames only FILES=$(find $IN -type f -regex ".*/[0-9 ]*") ## recursive; numeric filenames only (may include spaces) # echo '$FILES:' ## single-quoted, (literally) prints: $FILES: # echo "$FILES" ## double-quoted, prints path/, filename (one per line) # ---------------------------------------------------------------------------- # MAIN LOOP: for f in $FILES do # Tag top of file with basename of current dir: printf "[top] Tag: ${PWD##*/}\n\n" | cat - $f > temp && mv -f temp $f # Tag bottom of file with basename of current dir: printf "\n[bottom] Tag: ${PWD##*/}\n" >> $f done unset IFS; set +f 
 echo -n "text to insert " ;tac filename.txt| tac > newfilename.txt 

Il primo tac reindirizza il file all’indietro (prima l’ultima riga) quindi il “testo da inserire” appare per ultimo. Il secondo tac avvolge di nuovo così la riga inserita è all’inizio e il file originale è nel suo ordine originale.

Per aggiungere una linea all’inizio del file:

 sed -i '1iText to add\' 

C’è un modo molto semplice:

 echo "your header" > headerFile.txt cat yourFile >> headerFile.txt 

Solo per divertimento, ecco una soluzione che usa ed non ha il problema di non lavorare su un file vuoto. Puoi inserirlo in uno script di shell come qualsiasi altra risposta a questa domanda.

 ed Test < . 1,+1 j $ g/^$/d wq EOF 

Lo script precedente aggiunge il testo da inserire nella prima riga e quindi unisce la prima e la seconda riga. Per evitare che l’errore si verifichi in caso di errore con un join non valido, crea prima una riga vuota alla fine del file e la rimuove in seguito se esiste ancora.

Limitazioni: questo script non funziona se è esattamente uguale a un singolo periodo.