Форум сайта python.su
Ребята помогите пожалуйста с таким вопросом! Думаю многие когда начинали изучать Python каким то образом с ним сталкивались!
Просто необходимо прошерстить весь сервак по словам напимер: @mycompany1.com и @mycompany1.com - (с возможностью исключить какие либо диектории и расширении файлов) и в тех файлах в которых встречаются эти слова:
1. Cделать бэкап этого файла так сказать на всякий случай (для отката)
Пример: Файл назывался script.pl и в эту же директорию ложиться его копия с названием script.pl.13_05_2017.backup12345
2. А в оригинальном файле (script.pl) сделать замену этих слов @mycompany1.com и @mycompany1.com на @mycompany3.com
Думаю может у кого будет готовый вариант, буду крайне благодарен!
Офлайн
На shell'е можно это быстрее и короче написать, чем на питоне.
Надо написать функции и связать их вместе.
1. Найти рекурсивно все файлы в заданной директории.
1.1. Если это не путь к файлу, то не включать его в результат.
2. Отобрать из файлов только нужные.
2.1. Загрузить критерии отбора.
2.2. Отфильтровать строки по загруженным критериям отбора.
3. Для каждого отобранного файла:
3.1. Сделать бэкап файла.
3.1.1. Сформировать имя для бэкапа.
3.1.2. Сохранить бэкап файл под сформированным именем.
3.2. Провести замену в файле.
3.2.1. Загрузить строки для поиска.
3.2.2. Загрузить строку для замены.
3.2.3. Заменить в файле строки поиска на строку замены.
Вот теперь можно для этого алгоритма (словесного описания алгоритма) написать псевдокод, чтобы урегулировать аргументы функций и их возвращаемые значения. И только после этого по полученному псевдокоду писать реальный код на любом языке программирования.
Отредактировано py.user.next (Май 14, 2017 00:54:59)
Офлайн
Можно и на shell'е - если это действительно проще!
Пока у меня получилось вот так: Правда код не доработан, может у кого есть какие идеи его немножко поправить в сторону циклов и рекурсии
———-
#!/bin/bash
# от какого каталога проверять
content=/registry
# по каким словам проверять
patterns='(mycompany1.com|mycompany2.com)'
# куда и под каким именем сохранять результат
result=/Alex/mytest.txt
# какие каталоги исключить из поиска
# excludes=
# какие расширения файлов проверять
# extensions=
find $content \( -path /home/clload/test1 -o -path /home/clload/test2 -o -path /home/clload/test3 \) -prune -o \( -name ‘*.c’ -o -name ‘*.pl’ -o -name ‘*.pm’ -o -name ‘*.sh’ -o -name ‘*.ksh’ -o -name ‘*.cpp’ -o -name ‘*.h’ -o -name ‘*.hpp’ -o -name ‘*.cfg’ -o -name ‘*.properties’ -o -name ‘*.ini’ -o -name ‘*.java’ -o -name ‘*.css’ -o -name ‘*.html’ -o -name ‘*.htm’ -o -name ‘*.js’ \) -exec egrep -rin $patterns ‘{}’ \; > $result
———-
Офлайн
AversusВ вашем случае похоже проще на питоне :)
если это действительно проще!
Офлайн
AversusЭто не то.
Пока у меня получилось вот так
get_paths()
{
find "$1" 2>/dev/null
}
paths_filter_files()
{
while read line; do
[ -f "$line" ] && echo "$line"
done
}
get_paths /etc | paths_filter_files
get_paths()
{
find "$1" 2>/dev/null
}
paths_filter_files()
{
while read line; do
[ -f "$line" ] && echo "$line"
done
}
files_filter_exts()
{
local exts=${1//|/\\|}
grep '\.\('"$exts"'\)$'
}
search_exts_in_directory()
{
local dir=$1
local exts=$2
get_paths "$dir" | paths_filter_files | files_filter_exts "$exts"
}
main()
{
search_exts_in_directory /etc "conf|xml"
search_exts_in_directory $HOME "jpg|jpeg|mp3|mp4|flv"
}
main | less
Отредактировано py.user.next (Май 15, 2017 12:30:11)
Офлайн
Посмотрел! Действительно скрипт отличный, пробегает по указанным директориям и выводить пути только тех файлов расширение которых указано в скрипте.
Было бы вообще здорово дополнить проверку этих файлов на: если есть в этих файлах слово @mycompany1.com и @mycompany1.com сделать бэкап этого файла и заменить эти слова на @mycompany3.com
Офлайн
Aversus
Было бы вообще здорово дополнить проверку этих файлов на: если есть в этих файлах слово @mycompany1.com и @mycompany1.com сделать бэкап этого файла и заменить эти слова на @mycompany3.com :)
get_paths()
{
find "$1" 2>/dev/null
}
paths_filter_files()
{
while read line; do
[ -f "$line" ] && echo "$line"
done
}
files_filter_exts()
{
local exts=${1//|/\\|}
grep '\.\('"$exts"'\)$'
}
search_exts_in_directory()
{
local dir=$1
local exts=$2
get_paths "$dir" | paths_filter_files | files_filter_exts "$exts"
}
files_filter_by_content()
{
local contents=${1//|/\\|}
while read line; do
grep -q "$contents" "$line" 2>/dev/null && echo "$line"
done
}
ymd()
{
date '+%Y-%m-%d'
}
make_backup_name()
{
sed 's/$/'".$(ymd).backup"'/'
}
show_convertion()
{
while read line; do
echo "$line ->"
echo -n " "
echo "$line" | make_backup_name
done
}
main()
{
search_exts_in_directory $HOME "txt|xml" | \
files_filter_by_content "user|server" | \
show_convertion
}
main | less
Офлайн
Спасибо! Кодик конечно не для новичков! Я попробовал но бекап не сделался, хотя консоль пишет:
/root/Test/test-1.txt -> /root/Test/test-1.txt.2017-05-15.backup
И куда тут вставлять слово @mycompany3.com на которое я хочу поменять @mycompany1.com и @mycompany1.com если они присутствуют в файле?
Значения подставил вот так:
main()
{
search_exts_in_directory /root/Test “txt|pl|sh” | \
files_filter_by_content “@mycompany1.com|@mycompany2.com” | \
show_convertion
}
Отредактировано Aversus (Май 15, 2017 14:52:49)
Офлайн
Это создание бэкапа и замена набора строк на одну строку:
get_paths()
{
find "$1" 2>/dev/null
}
paths_filter_files()
{
while read line; do
[ -f "$line" ] && echo "$line"
done
}
files_filter_exts()
{
local exts=${1//|/\\|}
grep '\.\('"$exts"'\)$'
}
search_exts_in_directory()
{
local dir=$1
local exts=$2
get_paths "$dir" | paths_filter_files | files_filter_exts "$exts"
}
files_filter_by_content()
{
local contents=${1//|/\\|}
while read line; do
grep -q "$contents" "$line" 2>/dev/null && echo "$line"
done
}
ymd()
{
date '+%Y-%m-%d'
}
make_backup_name()
{
sed 's/$/'".$(ymd).backup"'/'
}
make_backup()
{
local src=$1
local dst=$2
while [ -e "$dst" ]; do
dst="${dst}_"
done
cp "$src" "$dst"
}
replace_in_file()
{
local fname=$1
local pat=$2
local rep=$3
sed -i 's/'"$pat"'/'"$rep"'/g' "$fname"
}
convert_with_backup()
{
local pattern=${1//|/\\|}
local replacement=$2
local backup_name
while read line; do
backup_name=$(echo "$line" | make_backup_name)
make_backup "$line" "$backup_name"
replace_in_file "$line" "$pattern" "$replacement"
done
}
main()
{
search_exts_in_directory /tmp/test "txt|xml" | \
files_filter_by_content "user|server" | \
convert_with_backup "test1|test2" "testtest"
}
main
Офлайн
Проверил! Большое спасибо, все работает как надо) Очень нужный скрипт
Есть правда небольшие пожелания по его улучшении но это уже как получиться!
-Можно ли не учитывать регистр т.к. если вдруг встретиться такая запись @Mycompany.com - скрипт ее не обработает.
-Можно ли исключить какие либо директории из поиска - это было бы очень удобно, особенно если есть тестовые проекты которые незачем “лопатить”
-Конечно бывают ситуации когда есть записи вида cpp@poddomen.mycompamy1.com - естественно скрипт его не обработает. Можно ли что бы и такие записи учитывал, тут важно то что есть @, например запись с http://scientific.mycompany1.com/sm/corrections обрабатывать не нужно
-И если допустим директория или файл не читается или не записывается я так понимаю скрипт просто ничего не сделает, а продолжит обработку дальше!
Отредактировано Aversus (Май 15, 2017 17:11:40)
Офлайн