Поиск и замена в.htaccess файлах в linux

Мне нужно добавить эту строку в каждый файл.htaccess, который находится в /home/*/site/assets/.htaccess где * может быть любое количество каталогов глубоко

Мне нужно оштрафовать этот текст

RewriteRule ^(.*)$ /site/assets/sym/$1 [L,NS]

и добавьте строку над ним или замените его следующим

RewriteCond %{REQUEST_URI} !^/site/assets/sym
RewriteRule ^(.*)$ /site/assets/sym/$1 [L,NS]

Я смотрел в Интернете на этом сайте, но мне неясно, как бороться с

  1. создание списка файлов, которые я хочу редактировать (найдите все файлы, которые соответствуют этому пути: /home/*/site/assets/.htaccess)
  2. Добавление разрывов строк в тексте замены

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

Моя ОС - Cent OS 5.5, я использую сервер LAMP, если это имеет большое значение, apache 2.

Спасибо

2 ответа

Вы можете использовать sed, чтобы вставить линию над совпавшим шаблоном и делать резервные копии по мере продвижения.

for file in  $( find /home -name .htaccess | grep /site/assets/sym); do
    sed -i.bak '/RewriteRule \^(.\*)\$ \/site\/assets\/sym\/\$1 \[L,NS\]/i RewriteCond %{REQUEST_URI} !^/site/assets/sym' "$file"
done
  • sed -i.bak отредактирует файлы на месте и создаст файл.bak для каждого
  • /PATTERN/i другой шаблон - сопоставьте PATTERN и вставьте другой шаблон перед ним.

Вы выбрали отличный набор инструментов для работы!

Создать список файлов, которые вы хотите отредактировать, очень просто - я предполагаю, что вы используете оболочку, которая расширит вывод соответствующих имен файлов, таких как bash или dash:

echo /home/*/site/assets/.htaccess > list.txt

Однако если * может означать более 1 уровня каталогов, я бы пошел с этим:

find -name '.htaccess' /home | grep '/site/assets/sym' > list.txt

Ваша оболочка развернет выражение в список и перенаправит вывод в list.txt. Один файл для каждой строки.

Вы также можете искать файлы с именем.htaccess с помощью команды find - чтобы увидеть, есть ли кто-то, кого вы пропустили, например:

find -name '.htaccess' /home

Добавление разрывов строк в тексте замены - это немного зависит от вашего редактора. Разрывы строк обычно представлены как \n

То, что вы хотите сделать, вероятно, может быть достигнуто с помощью небольшого shell-скрипта - когда for variable in expression; do .... done используется, он будет выполнять строки между do / done один раз для каждого слова в выражении. ПРИМЕЧАНИЕ. Это может иметь неприятные последствия, если пути содержат пробелы.

for file in /home/*/site/assets/.htaccess; do
    sed 's/RewriteRule \^(.\*)\$ \/site\/assets\/sym\/\$1 \[L,NS\]/RewriteCond %{REQUEST_URI} !^\/site\/assets\/sym\nRewriteRule \^(.\*)\$ \/site\/assets\/sym\/\$1 \[L,NS\]/g' $file > $file.new
    mv $file $file.old
    mv $file.new $file
done

(Это оставит файл с именем.htaccess.old на месте.)

Переписан для альтернативного подхода к сбору списков:

for file in $(find -name '.htaccess' /home | grep '/site/assets/sym'); do
    sed 's/RewriteRule \^(.\*)\$ \/site\/assets\/sym\/\$1 \[L,NS\]/RewriteCond %{REQUEST_URI} !^\/site\/assets\/sym\nRewriteRule \^(.\*)\$ \/site\/assets\/sym\/\$1 \[L,NS\]/g' $file > $file.new
    mv $file $file.old
    mv $file.new $file
done

Или в одну строку, без создания резервной копии:

for file in /home/*/site/assets/.htaccess; do sed -i 's/RewriteRule \^(.\*)\$ \/site\/assets\/sym\/\$1 \[L,NS\]/RewriteCond %{REQUEST_URI} !^\/site\/assets\/sym\nRewriteRule \^(.\*)\$ \/site\/assets\/sym\/\$1 \[L,NS\]/g' $file; done
Другие вопросы по тегам