¿Cómo insertar un texto al principio de un archivo?

Hasta ahora he podido encontrar cómo agregar una línea al principio de un archivo, pero eso no es exactamente lo que quiero. Lo mostraré en un ejemplo

Contenido del archivo

some text at the beginning 

Resultado

  some text at the beginning 

Es similar, pero no quiero crear ninguna línea nueva con él …

Me gustaría hacer esto con sed si es posible.

sed puede operar en una dirección:

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

¿Qué es este 1s mágico que ves en cada respuesta aquí? Direccionamiento de línea! .

¿Desea agregar en las primeras 10 líneas?

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

O puede usar la Command Grouping :

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

Si el archivo es solo una línea, puede usar:

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

Si es más de una línea uno de:

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

He incluido el último para que sepas cómo hacer rangos de líneas. Ambos “reemplazan” el marcador de línea de inicio en sus líneas afectadas por el texto que desea insertar. También puedes (suponiendo que tu sed sea ​​lo suficientemente moderno) usar:

 sed -i 'whatever command you choose' filename 

para hacer la edición en el lugar.

Si desea agregar una línea al principio de un archivo, debe agregar \n al final de la cadena en la mejor solución anterior.

La mejor solución agregará la cadena, pero con la cadena, no agregará una línea al final de un archivo.

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

Puedes usar cat -

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

Para insertar solo una nueva línea:

 sed '1i\\' 

Tenga en cuenta que en OS X, el sed -i file falla. Sin embargo, si proporciona una extensión de copia de seguridad, sed -i old file , entonces el file se modifica en su lugar mientras se crea file.old . A continuación, puede eliminar file.old en su secuencia de comandos.

Hola con devolución de carro:

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

PROBLEMA: etiqueta un archivo, en la parte superior del archivo, con el nombre base del directorio principal.

Es decir, por

 /mnt/Vancouver/Programming/file1 

marque la parte superior del file1 con la Programming .

SOLUCIÓN 1 – archivos no vacíos:

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

1s coloca el texto en la línea 1 del archivo.

SOLUCIÓN 2 : archivos vacíos o no vacíos:

El comando sed , arriba, falla en los archivos vacíos. Aquí hay una solución, basada en 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  

Tenga en cuenta que se requiere el comando - in the cat (lee la entrada estándar: consulte man cat para obtener más información). Aquí, creo, es necesario tomar el resultado de la instrucción printf (a STDIN), y cat eso y el archivo a temperatura … Ver también la explicación en la parte inferior de http://www.linfo.org/cat .html .

También agregué -f al comando mv , para evitar que se me pidieran confirmaciones cuando sobrescribía archivos.

Para recurse sobre un directorio:

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

Tenga en cuenta también que esto romperá caminos con espacios; hay soluciones en otros lugares (p. ej., archivo globbing, o find . -type f ... -type solutions) para esas.

ADDENDUM: Re: mi último comentario, este script le permitirá recurse sobre directorios con espacios en las rutas:

 #!/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 

El primer tac canaliza el archivo hacia atrás (la última línea primero), por lo que el “texto para insertar” aparece al final. El segundo tac lo vuelve a enrollar para que la línea insertada esté al principio y el archivo original esté en su orden original.

Para agregar una línea al principio del archivo:

 sed -i '1iText to add\' 

Hay una manera muy fácil:

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

Solo por diversión, aquí hay una solución que usa ed que no tiene el problema de no trabajar en un archivo vacío. Puede ponerlo en un script de shell al igual que cualquier otra respuesta a esta pregunta.

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

La secuencia de comandos anterior agrega el texto para insertar en la primera línea, y luego se une a la primera y segunda línea. Para evitar la salida ed en el error con una unión inválida, primero crea una línea en blanco al final del archivo y lo elimina más adelante si todavía existe.

Limitaciones: este script no funciona si es exactamente igual a un solo período.