поиск и добавление шаблона в большой файл - PullRequest
3 голосов
/ 19 января 2012

У меня большой файл конфигурации apache, и в каждом из разделов виртуального хоста я хочу добавить свою собственную запись в журнал.Мне интересно, могу ли я сделать это с помощью скрипта.

Мой текущий файл конфигурации выглядит примерно так:

ServerName abc.com   
some information.   
…   
……   

, и я хочу, чтобы он был похож на;

ServerName abc.com    
CustomLog "/usr/local/logs/abc.com.log"    
some information.    
…   
……       

Возможно ли это по какому-то сценарию?У меня есть много-много таких записей виртуального хоста, поэтому ручное обновление невозможно .. Любые идеи?

Ответы [ 5 ]

5 голосов
/ 19 января 2012

Сед быстро поработает над этим:

sed 's=^ServerName \(.*\)=&\nCustomLog "/usr/local/logs/\1.log"='

Редактировать: Я ранее опубликовал что-то еще, затем пошел и проверил это, и я сделал ошибку.Поэтому я проверил ответ Чоробы, обнаружил, что он тоже не совсем работает, поэтому исправил его и упростил.

1 голос
/ 19 января 2012

awk может быть намного проще в использовании.

awk 'NR==3{print "my log"}1' INPUT_FILE
  • NR - это встроенная переменная, которая отслеживает номера строк.
  • Вы также можете использовать -v и variable name для динамической передачи значений вместо жесткого кодирования в сценарии. например. awk -v line="$var" 'NR==line{print "my log"}1' INPUT_FILE. В этом случае line является переменной awk, а $var может быть вашей переменной bash, определенной вне области действия awk's.

Тест:

[jaypal:~/Temp] cat file
ServerName abc.com   
some information.   
…   
……  

[jaypal:~/Temp] awk 'NR==3{print "my log"}1' file # add log after 2 lines
ServerName abc.com   
some information.   
my log
…   
……  

[jaypal:~/Temp] awk 'NR==4{print "my log"}1' file # add log after 3 lines
ServerName abc.com   
some information.   
…   
my log
……  

[jaypal:~/Temp] var=2 # define a variable which holds the line number you want to print on
[jaypal:~/Temp] awk -v line="$var" 'NR==line{print "my log"}1' file
ServerName abc.com   
my log
some information.   
…   
……  

В комментариях я видел ваш вопрос о добавлении вашего журнала после 3 строк, начиная с сопоставленного шаблона (в данном примере ServerName). Для этого вы можете попробовать что-то вроде этого -

awk '/ServerName/{a=NR;print;next} NR==(a+3){print$0;print "my log";next}1' file

[jaypal:~/Temp] awk '/ServerName/{a=NR;print;next} NR==(a+3){print$0;print "my log";next}1' file
ServerName abc.com   
some information.   
…   
……  
my log
1 голос
/ 19 января 2012

Попробуйте этот сценарий sed:

sed -i~ '/^ServerName /s=^serverName \(.*\)=&\nCustomLog "/usr/local/logs/\1.log"=' config_file*

(не проверено)

0 голосов
/ 20 января 2012

Это добавляет желаемую строку после 3 после правильного ServerName.

perl -i~ -ne'
   print;
   $target = $.+3 if /^\QServerName abc.com\E\s*$/;
   print qq{CustomLog "/usr/local/logs/abc.com.log"\n}
      if $target && $. == $target;
' apache.conf
0 голосов
/ 19 января 2012

На самом деле ни один из ответов не работал для меня, когда я попробовал их на своем Mac по следующим причинам:

  • sed требует \ перед открытием и закрытием скобок для группировки
  • Помещение \n в шаблон замены просто вставляет n.
  • Bakrereference \1 не работает для a операции

Вот команда, которая сработала:

sed -i.bak 's~^ServerName \(.*\)$~&\
CustomLog "/usr/local/logs/\1.log"~g' *.conf
...