Comment faire précéder récursivement un en-tête de licence pour tous les files .h et .cpp d'un directory

J'essaie d'append un en-tête de licence à tous les files d'en-tête et les files source dans un directory de projet en utilisant une boucle for. Cela ne fonctionne pas, y a-t-il une autre approche utilisant sed ?

 for f in **/*.cpp; do cat header_file $f > $f.new mv $f.new $f done 

C'est plus ou less juste un commentaire prolongé sur la réponse de Daniel Serodio . J'ai commencé à l'écrire en tant que commentaire, mais il est rapidement devenu trop grand …

Pour qu'un bash-glob soit récursif, il faut shopt -s globstar . Vous devez activer globstar, sinon ** ne fonctionne pas. L'option shell globstar a été introduite dans la version 4 de bash.

Pour éviter de traiter un directory tel que my.cpp/ , utilisez le test [[ -f $f ]] … Lorsque le test est entre crochets, les variables n'ont pas besoin d'être doublées.

Vous pouvez également envisager la possibilité qu'il n'y ait pas de files correspondants en utilisant shopt -s nullglob , qui autorise les templates qui ne correspondent à aucun file à se développer en une string shopt -s nullglob plutôt qu'en eux-mêmes.

Pour gérer plusieurs templates, vous pouvez enstringr les templates glob: **/*.cpp **/*.h , mais peut-être préférablement, lorsque l'option shell extglob est shopt -s extglob via shopt -s extglob , **/*.@(cpp|h) qui évite les passages multiples sur le système de files; une fois pour chaque motif.

Si vous voulez .files .*.cpp Utilisez .*.cpp etc, ou utilisez shopt -s dotglob

Pour gérer en toute security la modification d'un file en cours de traitement, utilisez l' sponge du package moreutils (vous moreutils de créer votre propre file temporaire)


 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 

Vous pouvez le faire avec ex ou ed si vous préférez (vous ne devriez pas le faire avec sed comme vous l'avez demandé, sed est conçu pour éditer des stream, c'est une mauvaise idée pour diverses raisons):

 shopt -s globstar for _file in **/*.@(cpp|h); do ed -s "${_file}" << EOF 0a /* This file is licensed under the foo license. All copyright ssortingctly enforced by the copyright monster. */ . w EOF done 

Merci @fred, @maxmackie, @enzotib.

Pouvez-vous vérifier la procédure que j'ai suivie?

 #!/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 copyd to $f" fi done 

sinon l'en-tête de licence sera copié plusieurs fois.

Veuillez me suggérer un model pour parcourir tous les en-têtes et les sources dans le directory et les sous-directorys du projet.

Je ne pouvais pas comprendre complètement ce que @fred a suggéré.

Le blog de Gerhard Gappmeier – Comment replace récursivement les en-têtes des files source

Le blog a attaché un file tar.gz contenant les files nécessaires.

Il a un file header.template , où vous pouvez écrire un commentaire personnalisé, il peut s'étendre sur plusieurs lignes.

Il a un script remove_header.awk qui remplace les en-têtes existants par le nouvel en-tête.

Pour l'exécuter:

 find . -name "*.h" -exec ~/rh/replace_header.sh {} \; 
 #!/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