Добавление строки текста в несколько файлов

10

Итак, у меня есть куча файлов в каталоге, и мне нужно вставить строку текста в каждый из них. По сути, они имеют следующий формат:


<VirtualHost *:80>
        ServerAdmin gabe@localhost
        DocumentRoot /var/www/test1
        ServerName test1.local
        ServerAlias test1
        <Directory "/var/www/test1">
                Options All
                AllowOverride All
        </Directory>
</VirtualHost>

И я хотел бы вставить строку до закрытия

</ VirtualHost>
тег. Мое первое предположение заключается в том, что я должен быть в состоянии сделать это с помощью sed, возможно, сопоставив и заменив этот тег. Я собираюсь начать пытаться сделать это сейчас, но если у кого-то есть существующий способ сделать это, я хотел бы услышать это.

Гейб.
источник
Я буду честен, когда скажу, что думаю, что это больше задача программирования ... и поэтому должно быть на SO. Я бы использовал Perl для этого, особенно если поспорить, что есть модуль perl, предназначенный для анализа и изменения настроек Apache.
ксенотеррацид
2
Спасибо, но это задача, которую легко выполнить с помощью простых инструментов Unix, поэтому она задается здесь. Спасибо за ваш комментарий, хотя.
таращиться

Ответы:

10

Что-то вроде этого:

sed 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/'

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

for i in *; do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' "$i"; done

Вероятно, лучше (но не проверено) благодаря @ChrisDown:

find . -type f -print0 | while IFS= read -r -d '' filename;\
do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' $filename;\ 
done
lcipriani
источник
офигенно ... это как раз то, что я искал.
таращиться
1
Вы не разобрать Ls. Вместо этого используйте шар. mywiki.wooledge.org/ParsingLs
Крис Даун
Вы правы @ChrisDown. Пожалуйста, улучшите мой ответ.
lcipriani
Выбор другого символа, нежели /для выражения sed, более понятен, так как вам не нужно избегать слэша:'s:</VirtualHost>:yourlinehere\n</VirtualHost>:'
Alexander
2

Если вы не возражаете против Perl, попробуйте:

perl -pi'*.old' -e 's(</VirtualHost>(Your stuff here\n</VirtualHost>)' myfile

-iКоммутатор будет сохранить старый файл с .oldрасширением и печатью на текущий.

gvkv
источник
2

Вы также можете использовать «ex» (командная строка vi), если редактирование, которое вы хотите сделать, даже несколько сложнее. Например, вы хотите выполнить вставку только для одного экземпляра "".

Такой сценарий оболочки может работать:

for FILENAME in *.whatever  # Need a criteria to glob, or a list of names
do
    ex -s $FILENAME << END_EDITS
/^<\/VirtualHost>/
O " capital-o, not zero
text to insert goes here
.
w!
q
END_EDITS
done

Этот подход дает вам преимущества «бывшего»: поиск местоположения со сложными узорами и «движения курсора». Вы можете сделать такие вещи, как найти шаблон, а затем найти следующий экземпляр, затем сделать вставку. Или вы можете изменить текст, а не просто делать вставки. Или вы можете переключаться между диапазонами. Не забывайте, что «ex» позволяет вам использовать «.» как текущая строка, так., / ^ somepatter / s / blah / foo / будет работать.

Брюс Эдигер
источник
0

Вы можете использовать следующий однострочный код для вставки одной или нескольких строк в определенное место в файле, в вашем случае до «VirtualHost». Код в основном ищет имя файла (это может быть *. *, Если вы хотите вставить текст во все файлы) в данном каталоге и его подкаталогах. В найденных файлах он ищет шаблон «VirtualHost». Найдя шаблон, он заменяет его на первую строку \ nsecondline \ notherlines \ n \ VirtualHost. Обратите внимание, что «VirtualHost» является частью текста для замены, в противном случае мы потеряем его.

find directory/ -name filename -print | xargs sed -i 's|VirtualHost|firstline\nsecondline\notherlines\nVirtualHost|g'
Oufie
источник