Я уверен, что есть более эффективные способы решения этой проблемы, но эта пара awk
скриптов выполнит свою работу. Вы можете использовать либо увеличенную версию с комментариями, либо однострочную версию ниже; они функционально идентичны.
awk '
BEGIN { RS="" } # Slurp paragraphs
{ print gensub("\n", " ", "g") } # Replace NL with SPACE
' /tmp/tnsnames.ora | # ...in this file
awk '
/SERVICE_NAME/ { # Only process matching lines
listener=$1; # Listener is the first field
si=NF-2; # Count fields back from end of string
service=gensub(")", "", 1, $si); # Strip trailing ")"
printf "%s\t%s\n", listener, service # Output result
}
'
Пример выполнения
awk 'BEGIN { RS="" } { print gensub("\n", " ", "g") }' /tmp/tnsnames.ora | awk '/SERVICE_NAME/ { listener=$1; si=NF-2; service=gensub(")", "", 1, $si); printf "%s\t%s\n", listener, service }'
NEWDB newdb
STEST STEST
RBSDB RBSDB
Можно выполнить через awk
следующим образом:
awk '{if($0 ~ /^HOST/){print "#"$0}else{print $0}}' file > file.conf
awk
будет читать данные из вашего файла, если строка начинается с HOST
, она напечатает строку с #
в начале, в противном случае напечатает как есть.
>
для сохранения результатов в file.conf
Perl one liner:
perl -pe 's/^HOST/#$&/' file
Или, чтобы отредактировать файл на месте:
perl -i -pe 's/^HOST/#$&/' file
-pe
означает p rint каждую строку ввода после применения сценария, заданного -e
. s / foo / bar /
является оператором замены и заменит первый экземпляр foo
на bar
в каждой строке. Здесь мы заменяем строки, начинающиеся с HOST
( ^
означает начало строки) на #
и все, что было найдено ( $ &
- это специальная переменная, в которой хранится то, что было найдено). Итак, мы заменяем HOST
на #HOST
.
perl однострочный:
$ perl -ne 'if(/^HOST/){print "#$_"} else { print}' input.txt
--------------------
NETWORKING=yes
#HOSTNAME=wls1.ebs-testsrvrs.com
# oracle-rdbms-server-12cR1-preinstall : Add NOZEROCONF=yes
NOZEROCONF=yes
--------------------
Этот простой однострочный алгоритм выполняет итерацию по всем строкам, проверяя, начинается ли строка с HOST
и добавляя к нему #
, в противном случае мы переходим к else
, который просто печатает строку без изменений.
Версия для Python того же самого будет следующая:
python -c "import sys;print '\n'.join([ '#' + l.strip() if l.startswith('HOST') else l.strip() for l in sys.stdin ])" < input.txt
Однако это работает немного по-другому, путем создания списка (или массива) строк, условной вставки самой строки или строки с добавленным #
. В конечном итоге массив объединяется в одну большую строку с элементами, разделенными новой строкой, и распечатывается.
В vi
:
:%s/^HOST/#&/
или
:g/^HOST/s//#&/
%
в первой команде означает «в весь буфер ", и это краткое обозначение 1, $
, то есть от первой строки до последней. &
в заменяющей части подстановки будет заменен на весь текст, соответствующий шаблону ( ^ HOST
).
Вторая команда применяет замену ( s
) ко всем строкам, совпадающим с ^ HOST
, используя глобальную команду ( g
), которая vi
, унаследованный от линейного редактора ed
.Во втором случае команда s
использует пустое регулярное выражение. Это заставляет повторно использовать последнее использованное регулярное выражение ( ^ HOST
в команде g
). Замена такая же, как и в первой команде.
С sed
:
sed 's/^HOST/#&/' input >output
или
sed '/^HOST/s//#&/' input >output
так же, как в vi
( sed
всегда применяет все команды к каждой строке ввода stream, поэтому мы не используем ничего вроде %
или g
явно с sed
).
Используйте sed с параметром -i
, чтобы отредактировать файл на месте. (Резервная копия оригинала будет сохранена как file.txt.bak
).
sed -i.bak 's / ^ \ (HOST. * \) / # \ 1 / g 'file.txt
Чтобы прочитать часть регулярного выражения:
^
соответствует началу строки.
()
захватывает соответствующий текст во временную внутреннюю переменную ( \ 1
).
\
необходим перед символами (
, так как ваша оболочка украдет их в противном случае.
. *
соответствует 0 или более символам.
Итак, начиная с начала строки, она соответствует строке HOST
, за которой следует любой текст, вплоть до новой строки. Если строка не соответствует, оставьте как есть.Если он совпадает, то # \ 1
напечатает #
, за которым следует текст между ()
.