Estoy tratando de agregar un encabezado de licencia a todos los archivos de encabezado y archivos de origen en un directorio de proyecto usando un bucle for. Esto no está funcionando, ¿hay algún otro enfoque que esté usando sed
?
Estoy tratando de agregar un encabezado de licencia a todos los archivos de encabezado y archivos de origen en un directorio de proyecto usando un bucle for. Esto no está funcionando, ¿hay algún otro enfoque que esté usando sed
?
Respuestas:
for f in **/*.cpp; do
cat header_file $f > $f.new
mv $f.new $f
done
globstar
bash para que esto funcione.
Esto es más o menos un comentario extenso sobre la respuesta de Daniel Serodio '' . Comencé a escribirlo como un comentario, pero rápidamente creció demasiado ...
Para que un bash glob sea recursivo, se requiere shopt -s globstar
. Debes habilitar globstar, de lo contrario **
no funciona. La opción de shell globstar se introdujo en la versión 4 de bash.
Para evitar el procesamiento de un directorio como my.cpp/
, use la prueba [[ -f $f ]]
... Cuando la prueba está entre corchetes dobles, no es necesario que se doblen las variables.
También puede considerar la posibilidad de que no haya archivos coincidentes mediante el uso shopt -s nullglob
, que permite que los patrones que no coinciden con ningún archivo se expandan a una cadena nula, en lugar de a sí mismos.
Para manejar múltiples patrones, puede encadenar los patrones glob: **/*.cpp **/*.h
pero quizás de manera preferible, cuando la opción de shell extglob está activada a través de shopt -s extglob
, puede usar construcciones tales como las **/*.@(cpp|h)
que evitan múltiples pases sobre el sistema de archivos; una vez para cada patrón.
Si desea .files
ser incluido, use .*.cpp
etc., o useshopt -s dotglob
Para manejar de manera segura la modificación de un archivo que se está canalizando, use sponge
desde el paquete moreutils
(le ahorra la necesidad de crear su propio archivo temporal)
printf "// The License\n\n" > /tmp/$USER-license
shopt -s globstar nullglob extglob
for f in **/*.@(cpp|h) ;do
[[ -f $f ]] && cat "/tmp/$USER-license" "$f" | sponge "$f"
done
[[
puede manejar con gracia un nulo $f
.
unset x; [ -f $x ] && echo exists
informes "existen" ... (arreglado)
**/*.@(cpp|h)
por$( find . -name "*.h" -name "*.cpp")
Gracias @fred, @maxmackie, @enzotib.
¿Puede por favor verificar el procedimiento que he seguido?
#!/bin/sh
# script to copy the headers to all the source files and header files
for f in *.cpp; do
if (grep Copyright $f);then
echo "No need to copy the License Header to $f"
else
cat license.txt $f > $f.new
mv $f.new $f
echo "License Header copied to $f"
fi
done
de lo contrario, el encabezado de la licencia se copiará varias veces.
Sugiérame un patrón para recorrer todos los encabezados y fuentes en el directorio y subdirectorios del proyecto.
No pude entender completamente lo que @fred ha sugerido.
targln=2; findln=$(sed -rne $targln'{\|// Copyright|=;q}' "$f"); if ((findln==targln));then
... pero, por supuesto, más allá de todo lo demás, pruébelo primero ... PD. Es normal que el curso aquí en Unix y Linux publique tales extras en su pregunta original, no como una respuesta ...
grep
, agregue la -q
opción a grep
. Siempre agregue comillas dobles $f
.
Puede hacerlo con ex
o ed
si lo prefiere (no debe hacerlo con sed
lo que solicitó, sed
está diseñado para editar transmisiones, -i
es una mala idea por varias razones):
shopt -s globstar
for _file in **/*.@(cpp|h); do
ed -s "${_file}" << EOF
0a
/* This file is licensed under the foo license.
All copyright strictly enforced by the copyright monster. */
.
w
EOF
done
sed -i
una mala idea?
sed -i
rompe enlaces simbólicos y enlaces duros, lo que resulta en un comportamiento inesperado. En el mejor de los casos, no es intuitivo, en el peor es activamente dañino.
#!/bin/bash
for i in `find . -name '*.[m|h]'` # or whatever other pattern...
do
echo $i
if ! grep -q Copyright $i
then
cat copyright.txt $i >$i.new && mv $i.new $i
fi
done
enter code here
Blog de Gerhard Gappmeier - Cómo reemplazar recursivamente los encabezados de archivos fuente
La publicación del blog ha adjuntado un tar.gz
archivo que contiene los archivos necesarios.
Tiene un header.template
archivo, donde puede escribir un comentario personalizado, puede abarcar varias líneas.
Tiene un remove_header.awk
script que reemplaza los encabezados existentes con el nuevo encabezado.
Para ejecutarlo:
find . -name "*.h" -exec ~/rh/replace_header.sh {} \;