В продолжение задачки о “Псевдо-ASP”
Как я и говорил - поиск пришлось организовывать внешний. Я создал паучка обходящего сайт, собирающего ссылки, ограничил его паутину только данным доменом, заставил удалять теги и сохранять страницы в базе данных. Полнотекстовый поиск в MySQL очень хорошо подходит для поиска по сайту.
Но ведь была скачана туева хуча страниц, и на каждой из них присутствовала поисковая форма, которая ссылалась на /search/default.asp . Естественно эта страница не была скачана, т.к. wget не умеет отправлять формы. Предстояло поменять action у форм во всех файлах.
Для начала я решил посмотреть - сколько же файлов нужно изменить…
$ find ./ -iname "*.asp*" | wc -l 1263 $
Впечатлило…
Вот наверное где пригодился бы виндовый DreamWeaver….. Как вы думаете? Только чтобы открыть такое колличество файлов ушел бы час. Благо я уже давно не использую эту бяку.
Я решил обратиться к старейшим и эффективнейшим средствам работы с текстами (кто не знает - все ниже перечисленные утилиты давно портированы на windows).
Прежде всего, чтобы обойти такое колличество файлов , которые распологаются в довольно разветвленном дереве каталогов мне понадобилась утилита find. Чуть выше я показал, как при помощи нее я посчитал кол-во файлов, имена которых удовлетворяли некоторому условию.
Далее хотелось бы отдать посредством опции -exec в утилите find все эти файлы на обработку потоковому редактору sed, но не тут-то было. sed отказался понимать имена файлов с символами “&” и “?” пришлось их экранировать самим же sed.
$ find ./ -iname "*.asp*" |sed 's/?/\?/g'|sed 's/&/\&/g' ./faq/default.asp?aid=15 ./sertificates/default.asp?aid=211&bid=221&val=1 ./sertificates/default.asp?aid=209&bid=215 ./sertificates/default.asp?aid=209&bid=216 ./sertificates/default.asp?aid=209&bid=249 ./sertificates/default.asp?aid=209&bid=250 ... ... ... $
Для наглядности я оставил часть вывода команды.теперь дело за малым - прочитать со стандартного ввода имена файлов и отдать их на обработку редактору - в чем нам поможет оператор while встроенный в bash
$find ./ -iname "*.asp*"|sed 's/?/\?/g'|sed 's/&/\&/g' | while read i; do echo $i ; done|head ./faq/default.asp?aid=15 ./sertificates/default.asp?aid=211&bid=221&val=1 ./sertificates/default.asp?aid=209&bid=215 ./sertificates/default.asp?aid=209&bid=216 ./sertificates/default.asp?aid=209&bid=249 ./sertificates/default.asp?aid=209&bid=250 $
Как видите вывод команды не изменился. Мы можем подставить в цикл любую команду оболочки , вместо echo. Подставляем sed, тщательно продумывая регулярное выражение , которое будет изменять action у формы
$ find ./ -iname "*.asp*"|sed 's/?/\?/g'|sed 's/&/\&/g' | while read i; do sed -e "s/action=\"[^\"]*search/default.asp[^\"]*\"/action=\"http://moipoisk.my\"/g" $i ; done |grep action $
Я специально добавил в конец программы grep action , чтобы не выискивать в общем потоке html-кода формы , проверяя на правильность. Теперь, когда мы видим, что все action заменены правильно можем указать редактору - не отправлять измененное содержимое в поток, а редактировать файлы на месте. Для этого служит опция -i редактора sed.
$ find ./ -iname "*.asp*"|sed 's/?/\?/g'|sed 's/&/\&/g' | while read i; do sed -i "s/action=\"[^\"]*search/default.asp[^\"]*\"/action=\"http://moipoisk.my\"/g" $i ; done $
Ну вот и всё. Теперь можно наслаждаться жизнью и не думать о колличестве файлов, в которых нужно вносить однообразные правки. Теперь уже не важно сколько файлов было, и сколько их будет в следующий раз. Даже с десятью тысячами файлов содружество find,sed и bash справится очень легко…. Стоит только правильно им рассказать - что , как и где заменять.