Нет необходимости в chroot, я часто генерирую wot-карты / диаграммы из отдельной базы данных gpg, чем моя основная (например, рабочая группа). для этого экспорта GNUPGHOME
export GNUPGHOME=/mnt/home/naftuli
cd $GNUGPHOME
gpg --list-keys
grep -v "^#" your_file | grep -v "^$" | less
Удалите строки, начинающиеся с "#", а также удалите пустые строки, чем отправьте результат на less
для лучшего отображения.
В случае сценариев bash
это возможно с помощью команды set -vn
. -v
указывает bash перейти в подробный режим, в котором также будут распечатаны прочитанные команды. -n
указывает bash только читать файл сценария, ничего не выполняя.
Пример:
$ cat ./testscript.sh
#!/bin/bash
# comment
set -vn
echo "Hello World" # another comment
$ ./testscript.sh
echo "Hello World" # another comment
Как видите, он игнорирует строки, начинающиеся с #
, но встроенные комментарии все равно распечатываются. Это, конечно, не идеально, но, по крайней мере, не требует каких-либо внешних инструментов, таких как grep
. Мне не известны такие возможности в других языках сценариев
Просто grep никогда не сможет удалить все комментарии (или только комментарии), потому что grep не понимает язык, который он просматривает. Чтобы понять, что такое комментарий, а что нет, вам понадобится лексер , который понимает этот конкретный язык.
Есть несколько ответов на SO о том, как удалить все комментарии из определенных языков программирования. Я добавлю сюда два примера.
Для C ответ Джоша Ли утверждает:
gcc -fpreprocessed -dD -E test.c
Которая запускает препроцессор, но сохраняет макросы.
Для python ответ unutbu (с небольшой адаптацией мной) пишет небольшой лексический анализатор с использованием tokenize:
import tokenize
import io
import sys
def nocomment(s):
result = []
g = tokenize.generate_tokens(io.BytesIO(s).readline)
for toknum, tokval, _, _, _ in g:
# print(toknum,tokval)
if toknum != tokenize.COMMENT:
result.append((toknum, tokval))
return tokenize.untokenize(result)
print(nocomment(sys.stdin.read()))
Затем вы можете написать по одному из них для каждого языка программирования и использовать кейс. Предполагая, что лексер python называется remove-comments.py
#!/bin/sh
case "$1" in
*.py)
remove-comments.py < "$1"
break
;;
*.c|*.C|*.cc)
gcc -fpreprocessed -dD -E "$1"
break
;;
*)
echo I do not know how to remove comments from $1, sorry
break
;;
esac
Дайте имя сценарию и добавьте лексеры для нужных / используемых языков . Это должна быть более или менее надежная конструкция для удаления комментариев из файлов разных типов. (Использование файла
вместо регистра в именах файлов также было бы более надежным).
Ну, это зависит от того, что вы подразумеваете под комментариями. Если только строки без #
, тогда может быть достаточно простого:
grep -v '#'
(но это вызовет такие строки, как echo '#'
, как комментарий). Если строки комментариев - это строки , начинающиеся с с #
, тогда вам может потребоваться:
grep -v '^#'
И если строки комментариев - это строки, начинающиеся с #
после некоторого необязательного пробела, тогда вы можете использовать:
grep -v '^ *#'
И если формат комментария совсем другой, этот ответ вам не поможет.
Как упоминалось в комментариях выше, формат "комментариев" в вашем случае имеет значение. Тем не менее, для некоторых случаев этого может быть достаточно, без необходимости создавать скрипт.
Читая вопрос, можно предположить, что вы уже используете grep
для поиска файлов, так что передайте его через другой grep
; примерно так:
grep your_pattern your_file | grep --perl-regexp --invert-match '(?:^;)|(?:^\s*/\*.*\*/)|(? :^\s*#|//|\*)'
Это все равно разрешит строки или строки, которые имеют символ "триггер" в другом месте строки, которые имеют комментарии в конце, как в echo "Hello World" # другой комментарий
, или которые являются частью многострочного комментария (кроме случаев, отмеченных в объяснении ниже.
Если это используется в качестве пост-фильтра для grep, то эти ограничения должны быть незначительными, так как большинство комментариев будет отфильтровано, и вы больше не будете беспокоиться о том, "что ваши глаза остекленеют".
Есть три шаблона, которые при необходимости можно модифицировать в соответствии с вашим случаем использования. Первый (?:^;)
отлавливает строки, начинающиеся с символа ;
. Должен быть первым, без пробелов. Второй отлавливает строки, начинающиеся с `/* ... */` в стиле комментария, с пробелами или без них. Третий
отлавливает строки, начинающиеся с #
, //
или *
, с пробелами или без них. *
в последнем шаблоне помогает поймать строку внутри многострочного комментария в /* ... */
, где обычно используется столбец *
для соединения первой и последней строки вместе. Например:
/************
*
* This is my
* multi-line
* comment.
*
************/
Обозначение (? ... )
вокруг каждого шаблона делает их "не захватывающими" шаблонами, в надежде увеличить скорость и уменьшить потребление ресурсов. Аргументы -Pv
в grep указывают ему использовать правила регулярных выражений Perl --perl-regexp
, что позволяет группировать не захватывающие шаблоны и позволяет работать оператору чередования |
, ни один из которых не работает в CLI grep. На странице руководства grep есть предупреждение, что опция -P является экспериментальной, поэтому проверьте ее, прежде чем использовать в своей системе. Опция --invert-match
указывает grep
на обратное соответствие, возвращая строки, которые не соответствуют шаблону. Их можно объединить и сократить до -vP
.
Причина использования этого фильтра в качестве постфильтра к обычному grep
заключается в трех моментах. Во-первых, вы можете делать обычную выборку и добавлять дополнительную работу по использованию этого фильтра только тогда, когда вы столкнетесь с проблемой слишком большого количества комментариев в выводе. (Меньше ввода и меньше используемых ресурсов). Во-вторых, вы, вероятно, уже разработали шаблоны, которые часто используете, и привычки, которые с ними связаны, и добавление дополнительных сложностей может их нарушить. Добавление дополнительной работы по отладке паттернов, когда в этом нет необходимости, является напрасной работой. В-третьих, он не очень хорошо работает с многострочными комментариями, но если вы уже искали в файле то, что вам нужно, то он удалит большинство, если не все, комментарии из результатов и послужит вашей цели.
Вот простой процесс удаления комментариев, т.е. все идет после '#' с использованием sed и awk.
[root@master]# cat hash
This is a program to remove comments from this file
#!/bin/bash
# comment
set -vn # comment
echo "Hello World" # another comment
echo "testscript for removing comments"
echo "Hello World" # another comment
echo 'This is a # sign' #comment
echo "This is a # sign" #comment
[root@master]# awk -F '#' 'BEGIN{OFS="#";} { if (!/#/) ;else $NF="";print $0}' hash | sed -n 's/#$//g;p'
This is a program to remove comments from this file
set -vn
echo "Hello World"
echo "testscript for removing comments"
echo "Hello World"
echo 'This is a # sign'
echo "This is a # sign"
Чтобы сделать это для bash (или файлов bourne shell) : вы можете воспользоваться bash'овским "declare -f functionname", который отображает functionname как с правильным отступом, так и с удаленными комментариями (так что вы получите удаленные комментарии, и в качестве бонуса отступ тоже будет хорошим) :
BEAUTIFIER () {
for f in "$@"; do
printf "%s" "
F_from_sh () {
$(cat "$f")
}
echo ___ beautified version of $f : _________________
declare -f F_from_sh | awk ' (NR > 2) && length>2' | sed -e 's/^ //'
" | bash
done
}
Затем используйте как:
BEAUTIFIER script1.sh script2.bash etc
Пожалуйста, обратите внимание: это избавит вас от всех комментариев скрипта, даже от первой строки "shebang"! Возможно, вы захотите также отобразить первую строку $f.