Sto cercando di aggiungere un'intestazione di licenza a tutti i file di intestazione e file sorgente in una directory di progetto usando un ciclo for. Questo non funziona, c'è qualche altro approccio che utilizza sed
?
Sto cercando di aggiungere un'intestazione di licenza a tutti i file di intestazione e file sorgente in una directory di progetto usando un ciclo for. Questo non funziona, c'è qualche altro approccio che utilizza sed
?
Risposte:
for f in **/*.cpp; do
cat header_file $f > $f.new
mv $f.new $f
done
globstar
in bash affinché questo funzioni.
Questo è più o meno solo un commento esteso alla risposta di Daniel Serodio . Ho iniziato a scriverlo come commento, ma è diventato rapidamente troppo grande ...
Perché un globo bash sia ricorsivo, richiede shopt -s globstar
. È necessario abilitare globstar, altrimenti **
non funziona. L'opzione shell globstar è stata introdotta alla versione 4 di bash.
Per evitare di elaborare una directory come my.cpp/
, utilizzare il test [[ -f $f ]]
... Quando il test è tra parentesi quadre doppie, non è necessario che le variabili siano racchiuse tra virgolette doppie.
Puoi anche considerare la possibilità che non ci siano file corrispondenti utilizzando shopt -s nullglob
, il che consente ai pattern che non corrispondono a nessun file di espandersi in una stringa nulla, anziché in se stessi.
Per gestire più pattern, è possibile concatenare i pattern glob :,**/*.cpp **/*.h
ma forse preferibilmente, quando l'opzione shell extglob è attiva tramite shopt -s extglob
, è possibile utilizzare tali costrutti come quelli **/*.@(cpp|h)
che evitano passaggi multipli sul file system; una volta per ogni modello.
Se vuoi .files
essere incluso, usa .*.cpp
ecc. O usashopt -s dotglob
Per gestire in sicurezza la modifica di un file che viene reindirizzato, utilizzare sponge
dal pacchetto moreutils
(consente di risparmiare la necessità di creare il proprio file temporaneo)
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
[[
può gestire con grazia un valore nullo $f
.
unset x; [ -f $x ] && echo exists
rapporti "esiste" ... (risolto)
**/*.@(cpp|h)
con$( find . -name "*.h" -name "*.cpp")
Grazie @fred, @maxmackie, @enzotib.
Potete per favore controllare la procedura che ho seguito.
#!/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
in caso contrario, l'intestazione della licenza verrà copiata su più volte.
Per favore, suggeriscimi uno schema per esaminare tutte le intestazioni e le fonti nella directory del progetto e nelle sottodirectory.
Non riuscivo a capire fino in fondo cosa ha suggerito @fred.
targln=2; findln=$(sed -rne $targln'{\|// Copyright|=;q}' "$f"); if ((findln==targln));then
... ma, naturalmente, al di sopra e al di là di tutto il resto, prima provalo a fondo ... PS. È normale per il corso qui su Unix e Linux pubblicare tali extra nella tua domanda originale, non come una risposta ...
grep
, aggiungere -q
un'opzione a grep
. Aggiungi sempre doppie virgolette $f
.
Puoi farlo con ex
o ed
se preferisci (non dovresti farlo sed
come richiesto, sed
è progettato per modificare i flussi, -i
è una cattiva idea per una serie di motivi):
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 cattiva idea?
sed -i
interrompe collegamenti simbolici e hardlink, con conseguente comportamento imprevisto. Nella migliore delle ipotesi non è intuitivo, nel peggiore dei casi è attivamente dannoso.
#!/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 di Gerhard Gappmeier - Howto sostituisce in modo ricorsivo le intestazioni dei file sorgente
Il post sul blog ha allegato a tar.gz
file contenente i file necessari.
Ha un header.template
file, dove puoi scrivere un commento personalizzato, può estendersi su più righe.
Ha un remove_header.awk
script che sostituisce le intestazioni esistenti con la nuova intestazione.
Per eseguirlo:
find . -name "*.h" -exec ~/rh/replace_header.sh {} \;