-->
Для начинающих Для знатоков Для души О нас См. также Лабораторная работа по реляционным СУБД и языку SQL Микро хаки: советы и приемы эффективной работы Этюд о героях невидимого фронта |
Генерация случайного телефонного справочника
Copyright(С) Олег П. Филон Возьмем любой текстовый файл, содержащий много русских слов. Далее мы будем из них случайным образом выбирать отдельные слова для якобы фамилий и названий улиц, поэтому в первую очередь преобразуем этот файл в список слов: ...$ tr -d '!-~'<russian.text|tr ' ' '\n'|tr -s '\n'>russian.words У программы tr, как у всех textutils, есть хорошая документация в виде info-файла, доступная через ...$ info -f textutils На всякий случай поясню, что первый вызов tr удаляет из текста почти все символы, кроме русских букв и пробелов. Второй вызов tr преобразует все пробелы в символы новой строки, а третий tr удаляет пустые строки. Для единообразия добавим еще одну трансформацию: ...$ tr Ю-Ъ ю-ъ<russian.words>words Эта трансляция символов преобразует прописные буквы в строчные. Такие странные диапазоны символов нужны из-за используемой в Интернете и в Юниксе кодировки КОИ-8, в которой буквы расположены вот в таком порядке: юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ Если у вас проблемы с ятями Ъ и ъ, для большинства текстов вполне хватит диапазонов 'Ю-Ч' и 'ю-ч'. Конечно, я не помню кодировку КОИ-8 наизусть, и не набивал эту строку вручную, а воспользовался вездесущим perl'ом: ...$ perl -e 'use locale;print grep/\w/,map{chr()}128..255' Возможно, это поможет вам разобраться с вашей кодировкой и справиться с различием регистра букв в вашей системе. Теперь мы хотим создать подобие телефонного справочника вот с такими пятью полями: 1. номер телефона 2. фамилия и.о. 3. улица 4. номер дома 5. номер квартиры и разделенными знаками табуляции. Для меня ближайшей программой, подходящей для этой задачи, является интерпретатор awk. Вот что у меня получилось - текст программы на языке AWK: BEGIN { # этот блок выполняется 1 раз при запуске скрипта while((getline word<"words")>0) { i++ # индекс words[i]=word # массив слов } srand() # инициализация датчика случайных чисел u=1000 # максимальное количество улиц в нашем справочнике b=100 # -- "" -- зданий на улице k=200 # -- "" -- квартир в здании } { # эти операторы выполняются для каждой строки n=int(i*rand()) # индекс превратился в размер массива m=int(i*rand()) # n и m - случайные числа # в заданном диапазоне s=int(1+i*int(u*rand())/u) # s - случайное,не более u разных print $1 "\t"\ words[n],\ substr(words[m],1,1)"."substr(words[m],2,1)".\t"\ words[s] "\t"\ int(b*rand()+1) "\t"\ int(k*rand()+1) } AWK необычный язык. Но стоит понять метафору, скрытую в нем, и программы станут вполне читабельными. AWK берет строки из стандартного ввода, разбивает их на слова, а дальше смотрит, нужно ли применять к строке или отдельным словам указанные операторы. Много лет назад без лишнего шума AWK стал работать со словами и со строками как с объектами, просто указывая контекст и выполняемые в нем операции. В нашем случае при старте подготовленный заранее список слов запоминается в массиве, а далее все строки обрабатываются одинаково. В языке AWK все массивы ассоциативные, то, что в Perl стало впоследствии хеш-массивом, но, как видите, с таким массивом можно обращаться как с обычным, индексируемым целым числом. Остался последний штрих. Пусть файл с программой на AWK называется "create-phones-db.awk". Подадим ему на вход список якобы телефонных номеров и сохраним результат в файле "phones.txt" ...$ seq 100000 200000|awk -f create-phones-db.awk>phones.txt Готово. Размер файла регулируйте по вкусу, и не забудьте удалить лишние файлы. |