Приклад виконання лабораторної роботи N5 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Приклад виконання лабораторної роботи N5



Приклад 1-1

Кожне друге слово кожного рядка вивести в окремий наступний рядок. Якщо в рядку тільки одне слово, нічого не робити.

Розв'язок виявляється найпростішим. У якості символу-роздільника в тексті використовується пробіл, отже, при виклику awk визначати роздільник явно не потрібно. Слова становлять поля. Ніяких спеціальних дій на початку або наприкінці обробки вживати не потрібно. При обробці кожного рядка слід спочатку вивести повний текст рядка ($0), а потім перевірити довжину другого поля рядка ($2). Якщо довжина цього поля - 0, то друге слово в рядку відсутнє, і нічого вживати не потрібно. Якщо довжина відмінна від 0, друге поле виводиться в наступний рядок.

Повний текст програми awk і протокол її виконання виглядає так:

bash2-2.05$ awk ' { \ /* вивід усього рядка */ print $0; \ /* перевірка 2-го слова и вывод его, если оно есть */ if (length($2)>0) print $2; \ }' Hum-Dum.txtHumpty-DumptySet on the wall.onHumpty-DumptyHad a greate fall.aAnd all the king's horses,allAnd all the king's man.allCan not Humpty,notCan not Dumpty,notHumpty-Dumpty,Dumpty-Humpty,Set on this wallonAgain.bash2-2.05$
 

Приклад 1-2

Перший символ кожного рядка замінити на перший символ наступного рядка. Останній рядок залишається без змін.

Розв'язок цього завдання складніше, але не набагато. Ми можемо виводити рядок тільки після того, як прочитаємо наступний рядок. Тому вводимо змінну buf, яка відіграє роль буфера для запам'ятовування попереднього рядка. При обробці першого рядка (номер рядка можна визначити по системній змінної NR) її повний уміст тільки запам'ятовується в буфері. При обробці будь-якого наступного рядка на печатку виводиться перший символ прочитаного рядка й текст рядка, запомненной у буфері (попереднього рядка) без першого символу. Після закінчення читання файлу в буфері залишається текст останнього рядка, який повинен бути також виведений. Для виділення першого символу рядка й залишку рядка без першого символу використовується функція substr().

Повний текст цієї програми awk і протокол її виконання виглядає так:

bash2-2.05$ awk ' /* після обробки останнього рядка виводиться останній буфер */ END { printf("%s\n",buf); } { \ /* при обробці першого рядка ця дія не виконується */ if (NR>1) { \  /* виводиться 1-й символ поточного рядка     */  /* і вміст буфера, починаючи з 2-го символу */  printf("%c%s\n",substr($0,1,1),substr(buf,2)); \ } \ /* поточний рядок запам'ятовується в буфері */ buf=$0; \ }' Hum-Dum.txtSumpty-DumptyHet on the wall.Humpty-DumptyAad a greate fall.And all the king's horses,Cnd all the king's man.Can not Humpty,Han not Dumpty,Dumpty-Dumpty,Sumpty-Humpty,Aet on this wallAgain.bash2-2.05$Script done on Thu Sep 5 08:42:09 2002
 

Приклад 1-3

У передостанньому рядку, який закінчується крапкою, поміняти місцями перше слово з останнім.

Розв'язок цього завдання більш складне. Складність полягає в тому, що ми не знаємо, який рядок повинна бути модифікована, поки не прочитаємо весь файл. Розв'язок полягає в тому, що поточна обробка файлу буде в основному полягати в збереженні рядків у буфері. Буфер повинен являти собою масив рядків, який буде містити всі рядки файлу. Разом з нагромадженням рядків у буфері ми визначаємо, чи є останній символ рядка крапкою, і запам'ятовуємо номера двох останніх рядків із крапкою. Після закінчення читання файлу буфер містить повний текст файлу, і ми знаємо номери останньої й передостанньої рядків із крапкою.

 У заключній обробці (по шаблонові END) ми перебираємо рядка, збережені в буфері. Якщо номер чергового рядка не збігається з номером передостаннього рядка із крапкою, друкуємо цей рядок без змін. Якщо ж це той самий рядок, то при печатці вона модифікується. Ми використовуємо функцію awk split(), яка розбиває рядок на поля, розділені заданим символом. Частини рядка містяться в заданий масив, а функція повертає число полів, яке вона виявила в рядку. У нашому випадку роздільником є пробіл, а полями - слова. На печатку виводиться спочатку останній елемент масиву - результату функції split(), потім усі елементи із другого по передостанній, і нарешті - перший елемент. Таким чином, у рядку, що друкується, перше й останнє слова міняються місцями.

Повний текст програми awk і протокол її виконання виглядає так:

bash2-2.05$ awk ' /* nlines - лічильник рядків у файлі,                      */ /* point1 і point2 - номера рядків, що закінчуються крапкою, - */ /* останньої й передостанньої відповідно             */ BEGIN { nlines=0; point1=0; point2=0; } /* основна обробка - після закінчення читання файлу    */ END { \ /* перебираються всі рядки, збережені в буфері */ for (i=1; i<=nlines; i++) { \   /* перевірка - чи збігається номер рядка з виявленим номером */    if (i==point2) {       \     /* якщо збігається - рядок розбивається на слова, слова */     /* містяться в масив bb; nw - число виділених слів */     nw= split(buf[i],bb," "); \     /* друкується останнє слово */     printf("%s ",bb[nw]); \     /* друкуються слова від другого до передостаннього */     for (j=2; j<=nw; j++) printf("%s ",bb[j]); \     /* друкується перше слово */     printf("%s\n",bb[1]); \     } \   else \     /* якщо номер не збігається, рядок друкується як є */     print buf[i]; \   } \ } \ /* обробка кожного прочитаного рядка */ { \ /* прочитані рядки накопичуються в буфері */ buf[++nlines]=$0; \ /* виділяється останній символ рядка */ k=substr($0,length($0),1); \ /* якщо це крапка, модифікуються номери останньої й */ /* передостанньої рядків із крапкою                 */ if (k==".") { point2=point1; point1=NR; } \ }' Hum-Dum.txtHumpty-DumptySet on the wall.Humpty-DumptyHad a greate fall.And all the king's horses,man. all the king's man. AndAnd all the king's man.Can not Humpty,Can not Dumpty,Humpty-Dumpty,Dumpty-Humpty,Set on this wallAgain.bash2-2.05$Script done on Thu Sep 5 08:44:36 2002
 

Приклад 2-3.1

У файлі query3 визначити товар з найбільшою різницею мінімальної й максимальної ціни

Розв'язок надзвичайний простої. Це тривіальний алгоритм пошуку максимуму, цикл перебору рядків організує для нас awk. Максимальна й мінімальна ціни становлять 3-е й 4-е поля рядка відповідно. Для ідентифікації товару слід запам'ятати також і його назва - поле 2. Роздільником полів у файлі query3 є символ "!", так що awk повинна викликатися з опцією -F, що визначає роздільник.

Повний текст програми awk і протокол її виконання виглядає так:

bash2-2.05$ awk -F! ' /* після закінчення обробки друкуються запомненные дані */ END { printf("%s: %f-%f=%f\n",pp,pmax,pmin,pmax-pmin) } /* при обробці кожного рядка */ { \ /* якщо це перший рядок, запам'ятовується мінімальна й    */ /* максимальна ціна й різниця між ними, а також ім'я  */ /* якщо рядок не перша, але різниця цін у ній перевищує */ /* запомненную раніше, ціни, різниця, і ім'я теж запам'ятовуються */    if ((NR==1)||($3-$4>pmax-pmin)) \     { pp=$2; pmin=$4; pmax=$3 } \ }'../metod/query3DUNK BASKETBALL PROFESSIONAL: 58.300000-40.800000=17.500000bash2-2.05$
 

Приклад 2-3.2

У файлі query2 визначити всіх покупців, у яких кредит вище за середнє

Розв'язок цього завдання вимагає перебрати всі рядки файлу двічі - спочатку для обчислення середньої суми кредиту, а потім для визначення покупців, у яких кредит вище за середнє. Тому при переборі рядків файлу awk у буфері зберігаються необхідні дані (ім'я покупця й кредит) усіх рядків і виконується нагромадження суми кредиту по всіх рядках. Роль буфера відіграють два масиви - один для імен покупців, а іншої - для їхніх кредитів.

При виконанні заключних дій сума кредиту усредняется, а потім перебираються збережені в буфері дані й виводяться ті з них, які відповідають умові.

Повний текст програми awk і протокол її виконання виглядає так:

bash2-2.05$ awk -F: ' /* початкові установки: число рядків -0, сума кредиту - 0 */ BEGIN { nn=0; cc=0 } /* заключні дії */ END {  /* усереднення */  cc/=nn; \  /* перебір збережених даних */  /* якщо кредит перевищує середній - печатка */  for (i=0; i<nn; i++) \    if (crd[i]>cc) printf("%s - %d\n",cust[i], crd[i]) \  } \ /* обробка кожного рядка: запам'ятовування імені й кредиту, */ /* нагромадження суми кредиту, підрахунок загального числа рядків */ { cust[nn]=$2; crd[nn]=$8; cc+=$8; nn++ } '../metod/query2TKB SPORT SHOP        - 10000VOLLYRITE             - 7000EVERY MOUNTAIN        - 10000WOMENS SPORTS         - 10000NORTH WOODS HEALTH CENTER - 8000STADIUM SPORTS        - 10000REBOUND SPORTS        - 10000THE POWER FORWARD     - 12000FAST BREAK            - 7000AT BAT                - 8000AL'S PRO SHOP         - 8000BOB'S FAMILY SPORTS   - 8000WHEELS AND DEALS      - 10000BOB'S SWIM, CYCLE, AND RUN - 7000bash2-2.05$
 

Приклад 2-3.3

У файлі query2 визначити покупця, який має максимальну цифру номера будинку.

Розв'язок задоволений простої, сам алгоритм пошуку максимуму не представляє інтересу, оборотний увага на роботу з номером будинку. Аналіз файлу query2 показує, що адреса є третім полем у файлі, а номер будинку (якщо він присутній) - завжди перше слово в адресі. Однак не у всіх адресах зазначений номер будинку, адреси без цієї складової можна просто виключити з обробки. Це можна зробити за допомогою шаблону. Номер будинку виділяється з адреси при помрщи функції split(), роздільником слів в адресі є пробіл.

Повний текст програми awk і протокол її виконання виглядає так:

bash2-2.05$ awk -F: ' /* початкове значення максимального номера -0 */ BEGIN { nn=0 } /* наприкінці друкується знайдені ім'я й адреса */ END { printf("%s: %s\n",cc,aa) } /* обробка рядків; шаблон задає обробку тільки тих рядків, */ /* у яких після 2-го символу: коштує одна або більш цифр, */ /* а за ними - пробіл                                         */ /.*:.*:[0-9]* / { \ /* виділення номера будинку */ split($3,a," "); \ /* виявлення й запам'ятовування максимуму */ if (a[1]>nn) { cc=$2; aa=$3; nn=a[1] } \ }'../metod/query2VOLLYRITE                 : 9722 HAMILTONbash2-2.05$
 

Приклад 2-3.4

У файлі query3 визначити суму продажів для кожного року.

Розв'язок знов-таки вимагає деякого нагромадження даних. Ми заздалегідь не знаємо навіть, у які роки здійснювалися продажі. Тому нам доведеться ввести два масиви із синхронною індексацією: в одному ми будемо фіксувати рік, а в іншому - число продажів цього року. При переборі рядків файлу випливає в кожному рядку виділяти рік продажу й перевіряти, чи є такий рік у нашому масиві років. Якщо такого року ні, ми додаємо новий елемент у масив років і встановлюємо відповідний йому новий елемент у масиві лічильників продажів в 1. Якщо такий рік уже є, ми збільшуємо відповідний йому новий елемент у масиві лічильників продажів на 1.

Повний текст програми awk і протокол її виконання виглядає так:

bash2-2.05$ awk -F! ' /* количестов років -0 */ BEGIN { nn=0 } /* по завершенню - роздруківка років і їх лічильників */ END { for (i=0; i<nn; i++)    printf("%s - %s\n",year[i],cnt[i]) } /* обробка кожного рядка */ { \ /* виділення року */ y=substr($5,8,2); \ /* перебір уже наявних років; якщо рік у поточному рядку */ /* збігається з одним із уже наявних - збільшення лічильника */ for (i=0; i<nn; i++) \ if (year[i]==y) { cnt[i]++; break } \ /* якщо рік не збіглися з жодним з наявних, додається */ /* новий рік з лічильником 1                            */ if (i==nn) { year[i]=y; cnt[i]=1; nn++ } \ }'../metod/query389 - 1090 - 21bash2-2.05$
 

 



Поделиться:


Последнее изменение этой страницы: 2020-12-09; просмотров: 64; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.137.192.3 (0.012 с.)