Я пытаюсь добавить заголовок лицензии ко всем заголовочным файлам и исходным файлам в каталоге проекта, используя цикл for. Это не работает, есть ли другой подход sed?
Я пытаюсь добавить заголовок лицензии ко всем заголовочным файлам и исходным файлам в каталоге проекта, используя цикл for. Это не работает, есть ли другой подход sed?
Ответы:
Это более или менее просто расширенный комментарий к ответу Даниэля Серодио . Я начал писать это как комментарий, но он быстро стал слишком большим ...
Для того чтобы bash glob был рекурсивным, требуется shopt -s globstar. Вы должны включить Globstar, иначе **не работает. Опция оболочки globstar была введена в версии 4 bash.
Чтобы избежать обработки каталога, такого как my.cpp/, используйте тест [[ -f $f ]]... Когда тест заключен в двойные квадратные скобки, переменные не должны заключаться в двойные кавычки.
Вы также можете рассмотреть возможность отсутствия подходящих файлов, используя шаблон shopt -s nullglob, который позволяет шаблонам, которые не соответствуют ни одному файлу, раскрываться в пустую строку, а не в себя.
Для того, чтобы обрабатывать несколько шаблонов, вы можете приковать шаблоны Глобы: **/*.cpp **/*.h, но , возможно , предпочтительно, когда вариант оболочка extglob находится на с помощью shopt -s extglob, вы можете использовать такие конструкции , такие , как , **/*.@(cpp|h)который позволяет избежать несколько проходов по файловой системе; один раз для каждого шаблона.
Если вы хотите, .filesчтобы вас включили, используйте и .*.cppт. Д. Или используйтеshopt -s dotglob
Чтобы безопасно обрабатывать изменения файла, который передается по конвейеру, используйте spongefrom package moreutils(это избавляет вас от необходимости создавать собственный временный файл)
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
[[может изящно обработать ноль $f.
unset x; [ -f $x ] && echo exists отчеты "существуют" ... (исправлено)
**/*.@(cpp|h)с$( find . -name "*.h" -name "*.cpp")
Спасибо @fred, @maxmackie, @enzotib.
Можете ли вы проверить процедуру, которой я следовал.
#!/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
в противном случае заголовок лицензии будет скопирован несколько раз.
Пожалуйста, предложите мне шаблон для просмотра всех заголовков и источников в каталоге проекта и его подкаталогах.
Я не мог полностью понять, что предложил @fred.
targln=2; findln=$(sed -rne $targln'{\|// Copyright|=;q}' "$f"); if ((findln==targln));then... но, конечно, помимо всего прочего, сначала тщательно проверь это ... PS. Разумеется, здесь, в Unix & Linux, можно публиковать такие дополнения в своем первоначальном вопросе, а не в качестве ответа ...
grep, добавьте -qопцию к grep. Всегда добавляйте двойные кавычки $f.
Вы можете сделать это с помощью exили, edесли хотите, (вы не должны делать это так, sedкак вы просили, sedпредназначен для редактирования потоков, -iэто плохая идея по разным причинам):
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плохая идея?
sed -iломает символические и жесткие ссылки, что приводит к неожиданному поведению. В лучшем случае это не интуитивно понятно, в худшем - активно вредно.
#!/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
Блог Герхарда Гаппмайера - Как рекурсивно заменить заголовки файлов исходных файлов
К сообщению в блоге прикреплен tar.gzфайл, содержащий необходимые файлы.
В нем есть header.templateфайл, в котором вы можете написать собственный комментарий, он может занимать несколько строк.
У него есть remove_header.awkскрипт, который заменяет существующие заголовки новым заголовком.
Чтобы запустить его:
find . -name "*.h" -exec ~/rh/replace_header.sh {} \;