Ответ 1
С grep
:
grep -v '^$\|^\s*\#' temp
Я хотел бы распечатать файл, содержащий ряд комментариев вроде:
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
# SSL Engine Switch:
В сущности, файл содержит несколько уровней отступов, где комментарий начинается с символа #
.
grep должен удалить пустые строки, а также строки, где перед текстом есть символ хеша (подразумевая, что это комментарии).
Я знаю, что пустые строки можно удалить с помощью: grep -v '^$'
Однако как я могу удалить строки с ведущими пробелами, а затем символ #
и распечатать только строки с реальным кодом? Я хотел бы сделать это в bash, используя grep и/или sed.
С grep
:
grep -v '^$\|^\s*\#' temp
С awk
:
awk '!/^ *#/ && NF' file
!/^ *#/
- означает строки выбора, которые не имеют пробела, за которыми следует символ #
NF
- означает выделение строк, которые не являются пустыми.&&
- это оператор and
, который гарантирует, что оба из вышеперечисленных истинны, затем распечатайте строку.Это, вероятно, проще с sed
чем grep
:
sed -e '/^[[:space:]]*$/d' -e '/^[[:space:]]*#/d' test.in
Или с ERE:
# Gnu sed need -re instead of -Ee
sed -Ee '/^[[:space:]]*(#|$)/d' test.in
С ERE grep может сделать это довольно легко:
# Not sure if Gnu grep needs -E or -r
grep -vE '^\s*(#|$)' test.in
# or a BRE
grep -v '^\s*\(#\|$\)' test.in
Код для GNU sed:
sed -r '/^(\s*#|$)/d;' file
$cat file
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
next line is empty
line with leading space
# line with leading space and #
LogLevel warn
#line with leading tab and #
line with leading tab
CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
# SSL Engine Switch:
$sed -r '/^(\s*#|$)/d;' file
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
next line is empty
line with leading space
LogLevel warn
line with leading tab
CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
Это нужно сделать:
sed 's/[[:space:]]*#.*//;/^[[:space:]]*$/d' file
На этом входе:
Hello everybody
# This is a comment and the previous line was empty
This is a genuine line followed by a comment # this is the comment
# and here a comment in the middle of nowhere
вы получите этот результат:
Hello everybody
This is a genuine line followed by a comment
Caveat. Этот метод не является на 100% надежным: если у вас есть знак фунта (#
), не начинающий комментарий, т.е. Он экранирован или внутри строки, ну, вы можете себе представить, что произойдет.
grep ^[^#] filename
^
- начало строки
[^#]
- исключить #.
Если у вас есть пробелы в начале строки, это не сработает.
Маленькое обновление
grep -v '^\s*$\|^#\|^\s*\#' filename
Этот код исключает пустые строки или строки только пробелами, строки, начинающиеся С#, и строки, содержащие только пробелы перед #.
PS: ^#
отличается от ^\s*#
egrep -v '^$|^#' /etc/sysctl.conf
Использование разделителя пространства по умолчанию
так что держите его простым
awk '$1 ~ /^[^#]/ ' YourFile
grep -v '^$\|^#\|^\s*\#' filename
Исключает пустые строки, строки, начинающиеся С#, и строки, содержащие только пробелы перед #.
cat filename| egrep -v "^\s*$|^;|^\s*#
cat
файлegrep -v
удаляет^$
начиная с пустой строки^;
начиная с ;
^\s
соответствует любому ведущему пробелу, затем любой символ до #
#!/bin/bash
#---------------------------------------------------------------#
# Programacion Shell #
# ------------------ #
# Programa: xable.sh (eXecutABLEs) #
### ###
# OBJETIVO: Filtrar solo las lineas ejecutables de un shell #
# (eXecutABLEs) #
### ###
# Autor...: Francisco Eugenio Cabrera Perez #
# Pais....: Republica Dominicana #
# Fecha...: Abril 6 del 2015 #
#---------------------------------------------------------------#
x_FILE=$1
if [ -z $x_FILE ];then
echo
echo " $0 : Sin Argumento^G"; echo
echo "USO: $0 ARCHIVO"; echo
###
exit 1
fi
#####
# Ignore COMMENTs and lines that...
# ---------------------------------
# EXPLANATION (PATTERN) OBSERVATION
# ----------- --------- -----------
# 1. Begin_and_End_with_NOTHING (^$) NO_Characters
###
# 2. Begin_with_HASH_symbol (^#) COMMENT
# 3. Begin_with_SPACE_and_then_HASH_symbol (^\s*\#) COMMENT
###
# 4. Begin_and_End_with_SPACES (^[[:space:]]*$) Only_SPACES
# -------------------------------------------------------------------------
#####
grep -v '^$\|^#\|^\s*\#' $x_FILE | grep -v "^[[:space:]]*$" | more
#####
grep -v '^$\|^#\|^\s*\#' filename | grep -v "^[[:space:]]*$" | more
С Perl:
perl -lne 'print if ! /^\s*(#.*)?$/' file
Это также игнорирует комментарии С++ (//)
perl -lne 'print if ! m{^\s*((#|//).*)?$}' file
sed -n '/^\s*[^#]\|^$/!'p filename
Шаблон будет соответствовать любому количеству пробелов (или нулю), начинающихся в начале строки и следующих за любым символом, который не является #
ИЛИ пустая строка (ничего не происходит между символами ^ и $).
Чтобы не соответствовать этому, sed позволяет использовать оператор ! (инвертировать совпадение). Теперь шаблон соответствует любому, что регулярное выражение не подходит.
Таким образом, с помощью комбинации -n (подавления печати чего-либо) и печати p будут напечатаны строки, соответствующие чему-либо, кроме шаблона.