¿Cómo puedo anteponer una etiqueta al comienzo de varios archivos?

18

Necesito agregar etiquetas PHP que rodean un archivo. Es fácil agregarlos usando

find . -exec echo "?>" >> '{}' \;

pero, ¿cómo puedo anteponer la etiqueta <?php?

Gilles 'SO- deja de ser malvado'
fuente

Respuestas:

18
sed -i "1s/^/<?php /" file

(El -ies para editar en el lugar).

Versión más portátil:

ed file <<!
1s/^/<?php /
wq
!
usuario1686
fuente
ingenioso - que es un poco más fácil que lo que estaba a punto de describir :)
Warren
Necesito agregar la extensión al argumento -i aquí. ¿Estás usando sed o GNU sed?
Richard: El que estoy usando dice ser GNU sed, y permite agregar un sufijo de respaldo.
user1686
2
Estoy usando BSD sed, y permite la edición en el lugar, pero necesito darle una extensión. es decir, 'sed -i .bak "PATTERN" file'
3
-ino es portátil, la sintaxis difiere entre implementaciones y rompe enlaces simbólicos. Sería mejor usar una aplicación que esté diseñada para editar archivos.
Chris Down
5

Podrías usar un AWKfiltro como este,

awk '{if (NR == 1) printf "% s% s", "PREFIJO", $ 0; sino imprimir $ 0} 'testfile> newfile

¿Dónde PREFIXestá tu cadena de prefijo php?

nik
fuente
5

Todavía no puedo dejar un comentario, pero hacerlo todo en un solo paso:

find . -type f -exec sed -i -e "1s/^/<?php /" -e "\$s/\$/ ?>/" {} \;

fuente
Me encanta, me salvó horas.
Steve Hill
5

Puedes hacer eso con un perl one-liner:

perl -0777 -p -i -e "s/^/hey /g" testfile

Las -0777fuerzas de archivos sorber modo, por lo que todo el archivo se leen como una sola línea. -ppermite el bucle. -ipermite la edición en el lugar del archivo. ^indica el comienzo de una línea.

$ cp testfile1 testfile; perl -0777 -p -i -e "s/^/hey /g" testfile; diff testfile testfile1
1c1
< hey asdf
---
> asdf

Actualización: como se indica en los comentarios, puede optar por generar automáticamente una copia de seguridad utilizando en -i.baklugar de -i. Esto proporciona seguridad adicional en caso de errores en su comando. El argumento a se -i convierte en el sufijo de la copia de seguridad.

Al actualizar un montón de archivos, puede ejecutar el comando con -i.backup${RANDOM}, verificar que todos los archivos se hayan actualizado correctamente y luego eliminar todos los archivos con esa extensión.

nagul
fuente
1
"El valor 0777 hará que Perl sorba los archivos completos porque no hay un byte legal con ese valor", vea sial.org/howto/perl/one-liner/#s3.5
Chris W. Rea,
1
Si recomienda el uso de la -ibandera sin sufijo, advierta a los lectores que esto significa que no obtendrá copia de seguridad . Para algunos caracteres más ( -i.bak), obtendrá una copia de seguridad en caso de que su línea única incluya un error tipográfico. Un error tipográfico bastante simple (digamos, olvidando la -pbandera) puede arruinar su día entero de lo contrario.
Telemachus
@Telemachus - De acuerdo. Actualizado.
4

sedes para editar transmisiones: un archivo no es una transmisión. Utilice un programa destinado a este fin, como edo ex. La -iopción sedno solo no es portátil, sino que también romperá cualquier enlace simbólico que pueda encontrar, ya que esencialmente lo elimina y lo recrea, lo cual no tiene sentido.

for file in foo bar baz; do
    ed -s "${file}" << EOF
0a
<?php 
.
w
EOF
done
Chris Down
fuente
Lo que presentó es una forma básica de editar un solo archivo. Esto no parece responder al problema: la pregunta es sobre la modificación de una serie de archivos (aunque puede no ser obvio a primera vista). Si sabe cómo usarlo edpara ese propósito, muéstrelo en su respuesta.
rozcietrzewiacz
@rozcietrzewiacz: dado que Grawity demostró el mismo método de edición de un solo archivo (que fue aceptado), pensé que era apropiado para la respuesta. De cualquier manera, lo pongo en un bucle for, lo que debería aliviar sus preocupaciones.
Chris Down
0

Una alternativa a lo que escribió para agregar algo al final de cada archivo en el directorio (en bash):

for FNAME in *
do
    echo "?>" >> $FNAME
done

aunque me gusta tu findone-liner :)

madriguera
fuente
$FNAMEdebería ser $fname: por convención, capitalizamos las variables de entorno (PAGER, EDITOR, SHELL, ...) y las variables internas de shell (BASH_VERSION, RANDOM, ...). Todos los demás nombres de variables deben contener al menos una letra minúscula. Esta convención evita anular accidentalmente variables ambientales e internas.
Chris Down
@Chris Down: la convención que he visto durante toda mi carrera ha variado según la configuración: minúscula, mayúscula y camelcase :)
warren
Camelcase y minúsculas están bien. De cualquier manera, las variables que no son variables de entorno no deben estar en mayúsculas.
Chris Down
0

Hay una manera simple

echo "startstr$(cat filename)endstring" > filename.new
Hogan
fuente
Esto romperá con las nuevas líneas finales.
Chris Down
@ChrisDown arrastrando nuevas líneas en el archivo?
Hogan