2010-08-24 2 views
81

Мне нужно добавить следующую строку в конец файла конфигурации:Добавление строк в файл, только если он уже не существует

include "/configs/projectname.conf" 

в файл под названием lighttpd.conf

Ищу для использования sed, но я не могу понять, как это сделать.

Как бы вставить его, если линия еще не существует?

ответ

160

Просто держать его просто :)

Grep + эхо должно хватить:

grep -q -F 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar 

Edit: включены @Cerin предложение.

Примечание: для «редакторов» меняется мой ответ: если у вас есть альтернативное решение дать свой ответ! Редактирование предназначено для уточнения, форматирования, лучшего английского языка и так далее! Не изменяйте ответ, данный другими! (Спасибо)

+0

Это один делает обратное, что мне нужно. Он добавляет строку в файл, если строка уже существует. Я просто хочу добавить его, если он не существует. Есть идеи? –

+0

Извините, забыл опцию -v для grep или заменил && на || :) Я хочу исправить, спасибо – drAlberT

+2

Я бы добавил -q переключатель в grep для подавления вывода: 'grep -vq ...' –

3

Использование AWK

awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file file 
+0

Является ли это 'файлом' или просто 'файлом'? – webdevguy

+0

Это «файл», потому что он делает два прохода над одним и тем же файлом. 'NR == FNR' истинно на первом проходе, но не второй. Это обычная идиома Awk. – tripleee

11

Вот sed версия:

sed -e '\|include "/configs/projectname.conf"|h; ${x;s/incl//;{g;t};a\' -e 'include "/configs/projectname.conf"' -e '}' file 

Если строка в переменной:

string='include "/configs/projectname.conf"' 
sed -e "\|$string|h; \${x;s|$string||;{g;t};a\\" -e "$string" -e "}" file 
+0

Для команды, которая заменяет частичную строку полной/обновленной записью файла конфигурации или добавляет строку по мере необходимости: 'sed -i -e '\ | session. * Pam_mkhomedir.so | h; $ {x; s/mkhomedir //; {g; tF}; a \ '-e' session \ trequired \ tpam_mkhomedir.so umask = 0022 '-e'} ;: F; s /.* mkhomedir. */session \ trequired \ tpam_mkhomedir.so umask = 0022/g; '/etc/pam.d/common-session' – bgStack15

+0

Приятно, мне очень помогло +1. не могли бы вы объяснить, объясните свое выражение? – Rahul

+0

Мне бы хотелось увидеть аннотированное объяснение этого решения. Я использовал 'sed' годами, но в основном просто команда' s'. Переменные пространства 'hold' и' pattern' находятся вне меня. – nortally

0

мне нужно отредактировать файл с ограниченными разрешениями записи, поэтому необходимо sudo. работая от ответа ghostdog74 и используя временный файл:

awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file > /tmp/file 
sudo mv /tmp/file file 
+0

Это не выглядит правильным, оно потеряет другие строки из файла, если строка конфигурации отсутствует. – tripleee

1

другой SED решение, чтобы всегда добавить его в последней строке и удалить предварительно существующий.

sed -e '$a\' -e '<your-entry>' -e "/<your-entry-properly-escaped>/d" 

«правильно маскирование» означает поставить регулярное выражение, которое соответствует вашей записи, то есть, чтобы избежать всех регулярных выражений контролирующая из вашего actuall записи, т.е. поставить обратную косую черту Infront из^$/*? +().

это, возможно, не на последней строке файла или если нет запутывать новой строки, я не уверен, но это может быть съезжались с некоторыми изящным ветвлением ...

42

Это будет чистым, читаемые и многоразовое решение с использованием grep и echo, чтобы добавить строку в файл, только если он уже не существует:

LINE='include "/configs/projectname.conf"' 
FILE=lighttpd.conf 
grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE" 
+1

Если это файл, в котором вам нужны права root: 'sudo grep -qF" $ LINE "" $ FILE "|| echo "$ LINE" | sudo tee -a "$ FILE" ' – nebffa

+0

Это фактически не работает, когда строка начинается с' -'. – zsero

+0

@zsero: хорошая точка! Я добавил '--' в команду grep, поэтому он больше не будет интерпретировать $ LINE, начиная с тире как параметров. – rubo77

5

Если при записи в защищенный файл, @drAlberT и @ ответов rubo77 «ы может не работать для вы с тех пор не можете sudo >>.similarly simple solution, то было бы использовать tee --append:

LINE='include "/configs/projectname.conf"' 
FILE=lighttpd.conf 
grep -qF "$LINE" "$FILE" || echo "$LINE" | sudo tee --append "$FILE" 
Смежные вопросы