for f in **/*.cpp; do
cat header_file $f > $f.new
mv $f.new $f
done
Estou tentando adicionar um cabeçalho de licença a todos os arquivos de cabeçalho e arquivos de origem em um diretório de projeto usando um loop for. Isso não está funcionando, existe alguma outra abordagem usando sed
?
for f in **/*.cpp; do
cat header_file $f > $f.new
mv $f.new $f
done
Este é mais ou menos apenas um comentário estendido sobre a resposta Daniel Serodio '' . Eu comecei a escrevê-lo como um comentário, mas rapidamente cresceu muito ...
Para que um bash glob seja recursivo, ele requer shopt -s globstar
. Você deve ativar globstar, caso contrário **
não funcionará. A opção de shell globstar foi introduzida na versão 4 do bash.
Para evitar o processamento de um diretório como my.cpp/
, use o teste [[ -f $f ]]
... Quando o teste está em colchetes duplos, as variáveis não precisam ser duplamente citadas.
Você também pode considerar a possibilidade de não haver arquivos correspondentes usando shopt -s nullglob
, o que permite que os padrões que correspondem a nenhum arquivo sejam expandidos para uma cadeia nula, em vez de eles mesmos.
Para lidar com vários padrões, você pode encadear os padrões de glob: **/*.cpp **/*.h
, mas talvez de preferência, quando a opção de shell extglob estiver on via shopt -s extglob
, pode usar tais construções como **/*.@(cpp|h)
, o que evita várias passagens sobre o sistema de arquivos; uma vez para cada padrão.
Se você quiser que .files
seja incluído, use .*.cpp
etc ou use shopt -s dotglob
Para manipular com segurança a modificação de um arquivo que está sendo canalizado, use sponge
do pacote moreutils
(você evita a necessidade de criar seu próprio arquivo temporário)
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
Obrigado @fred, @maxmackie, @enzotib.
Você pode, por favor, verificar o procedimento que eu segui.
#!/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
caso contrário, o cabeçalho da licença será copiado para um número múltiplo de vezes.
Por favor, sugira-me um padrão para passar por todos os cabeçalhos e fontes no diretório e nos subdiretórios do projeto.
Eu não entendi totalmente o que o @fred sugeriu.
Você pode fazer isso com ex
ou ed
, se preferir (você não deve fazer isso com sed
conforme solicitado, sed
foi criado para editar fluxos, -i
é uma má ideia para um variedade de razões):
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
#!/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 - Como recursivamente substituir arquivo cabeçalhos de arquivos de origem
A postagem do blog anexou um arquivo tar.gz
, contendo os arquivos necessários.
Ele tem um arquivo header.template
, onde você pode escrever um comentário personalizado, ele pode abranger várias linhas.
Tem um script remove_header.awk
que substitui os cabeçalhos existentes pelo novo cabeçalho.
Para executá-lo:
find . -name "*.h" -exec ~/rh/replace_header.sh {} \;
Se você tem um header_file
com o conteúdo desejado:
find -name '*.cpp' -exec bash -c 'cat header_file \{} > \{}.new; mv \{}.new \{}' \;
find -name '*.h' -exec bash -c 'cat header_file \{} > \{}.new; mv \{}.new \{}' \;