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?
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?
Respostas:
for f in **/*.cpp; do
cat header_file $f > $f.new
mv $f.new $f
done
globstarbash para que isso funcione.
Este é mais ou menos apenas um comentário estendido sobre a resposta de Daniel Serodio . Comecei a escrever como um comentário, mas rapidamente cresceu muito ...
Para que um bash glob seja recursivo, é necessário shopt -s globstar. Você deve ativar o 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á entre colchetes duplos, as variáveis não precisam ser citadas duas vezes.
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 não correspondem a arquivos sejam expandidos para uma cadeia nula, e não para eles próprios.
Para lidar com múltiplos padrões, você pode encadear os padrões glob: **/*.cpp **/*.h, mas talvez de preferência, quando a opção shell extglob é na via shopt -s extglob, você 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ê deseja .filesser incluído, use .*.cppetc ou useshopt -s dotglob
Para manipular com segurança a modificação de um arquivo que está sendo canalizado, use spongefrom package moreutils(economiza 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
[[pode lidar normalmente com um nulo $f.
unset x; [ -f $x ] && echo exists relatórios "existe" ... (fixo)
**/*.@(cpp|h)por$( find . -name "*.h" -name "*.cpp")
Obrigado @fred, @maxmackie, @enzotib.
Você pode, por favor, verificar o procedimento que 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 vários números de vezes.
Por favor, sugira-me um padrão para percorrer todos os cabeçalhos e fontes no diretório e subdiretórios do projeto.
Não consegui entender completamente o que o @fred sugeriu.
targln=2; findln=$(sed -rne $targln'{\|// Copyright|=;q}' "$f"); if ((findln==targln));then... mas, é claro, acima e além de tudo o mais, teste-o primeiro ... PS. É par para o curso aqui no Unix e Linux para postar esses extras na sua pergunta original, não como uma resposta ...
grep, adicione a -qopção a grep. Sempre adicione aspas duplas $f.
Você pode fazer isso com exou edse preferir (não o faça sedconforme solicitado), sedfoi projetado para editar fluxos, -ié uma má ideia por vários motivos):
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 -iuma má ideia?
sed -iquebra links simbólicos e hardlinks, resultando em comportamento inesperado. Na melhor das hipóteses, não é intuitivo; na pior, é ativamente prejudicial.
#!/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
A postagem do blog anexou um tar.gzarquivo, contendo os arquivos necessários.
Ele tem um header.templatearquivo, onde você pode escrever um comentário personalizado, pode abranger várias linhas.
Ele possui um remove_header.awkscript que substitui os cabeçalhos existentes pelo novo cabeçalho.
Para executá-lo:
find . -name "*.h" -exec ~/rh/replace_header.sh {} \;