Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

pl:dydaktyka:unix:lab_sed_awk [2018/11/20 14:43]
kkutt [Do przygotowania]
pl:dydaktyka:unix:lab_sed_awk [2019/06/27 15:50]
Linia 1: Linia 1:
-====== SED i AWK ====== 
  
-{{:​pl:​dydaktyka:​unix:​evolution_of_language.gif?​400|}} 
-===== Do przygotowania ===== 
-  * Przypomnieć sobie pracę z jednym z wybranych edytorów (np. vi, emacs, itp). 
-  * Powtórzyć zasady pisania filtrów i skryptów powłoki sh. 
-  * Przypomnieć sobie funkcję manipulujące łańcuchami znaków w języku C. 
-  * Przeczytać następujące artykuły: ​ 
-    * Artykuł o //sed//: [[http://​gentoo-handbook.lugons.org/​doc/​pl/​articles/​l-sed1.xml|część 1]], [[http://​gentoo-handbook.lugons.org/​doc/​pl/​articles/​l-sed2.xml|część 2]], [[http://​gentoo-handbook.lugons.org/​doc/​pl/​articles/​l-sed3.xml|część 3]] (mirror: {{:​pl:​dydaktyka:​unix:​sed1.pdf|}},​ {{:​pl:​dydaktyka:​unix:​sed2.pdf|}},​ {{:​pl:​dydaktyka:​unix:​sed3.pdf|}}) 
-    * Artykuł o //awk//: [[http://​gentoo-handbook.lugons.org/​doc/​pl/​articles/​l-awk1.xml|część 1]], [[http://​gentoo-handbook.lugons.org/​doc/​pl/​articles/​l-awk2.xml|część 2]], [[http://​gentoo-handbook.lugons.org/​doc/​pl/​articles/​l-awk3.xml|część 3]] (mirror: {{:​pl:​dydaktyka:​unix:​awk1.pdf|}},​ {{:​pl:​dydaktyka:​unix:​awk2.pdf|}},​ {{:​pl:​dydaktyka:​unix:​awk3.pdf|}}) 
-  * Wersja angielska: 
-    * Artykuł o //sed//: [[https://​www.ibm.com/​developerworks/​linux/​library/​l-sed1/​index.html|część 1]], [[https://​www.ibm.com/​developerworks/​linux/​library/​l-sed2/​index.html|część 2]], [[https://​www.ibm.com/​developerworks/​linux/​library/​l-sed3/​index.html|część 3]]. 
-    * Artykuł o //awk//: [[https://​www.ibm.com/​developerworks/​linux/​library/​l-awk1/​index.html|część 1]], [[https://​www.ibm.com/​developerworks/​linux/​library/​l-awk2/​index.html|część 2]], [[https://​www.ibm.com/​developerworks/​linux/​library/​l-awk3/​index.html|część 3]]. 
- 
-  * Ciekawym miejscem do ćwiczenia znajomości wyrażeń regularnych jest [[https://​regexcrossword.com/​|Regex Crossword]] :-) 
-===== Wprowadzenie ===== 
-  * sed i awk są narzędziami strumieniowego przetwarzania tekstu. 
-  * Ich główną zaletą jest możliwość czytania ze standardowego wejścia i wyświetlanie rezultatów na standardowym wyjściu (dlaczego jest to zaleta?). 
-  * Dane mogą być wczytywane również z pliku. 
-  * Podczas pracy nie modyfikują żadnych plików. 
-  * Posiadają szereg instrukcji manipulujących łańcuchami znaków (wstawianie,​ zastępowanie,​ itp). 
-  * Instrukcje mogą być podawane z linii komend (w przypadku małych ilości poleceń) lub czytane z pliku (co zwiększa czytelność w przypadku dużej ilości poleceń). 
-  * Obsługują wyrażenia regularne!!! 
- 
-===== Wyrażenia regularne ===== 
-  * ang. //regular expressions//,​ w skrócie //regex// lub //regexp// 
-  * Są **wzorcami** opisującymi łańcuchy znaków. 
-  * Umożliwiają odnalezienie określonej regularności w danej sekwencji znaków. 
-===== Definiowanie wyrażeń regularnych ===== 
-  * Wyrażenia regularne składają się dwóch podstawowych zestawów znaków: 
-    * Znaki kontrolne: ''​. ? * + ^ | $ () [] {} \''​ 
-    * Zwykłe znaki: pozostałe 
-  * Kolejność znaków w wyrażeniu jest **istotna**. 
-  * Wielkość liter w wyrażeniu jest także **istotna**. 
-  * Wyrażenie **g** opisuje wszystkie łańcuchy znaków zawierające literę **g** np. //​**g**itara//​ (ale nie //​Gitara//​),​ //​za**g**adka//,​ //​lo**g**//​. 
-  * Wyrażenie **ba** opisuje wszystkie łańcuchy znaków zawierające podciąg **ba** np. //​**ba**ca//,​ //​za**ba**wa//,​ //​ża**ba**//​. 
-  * Kropka **.** określa dowolny znak oprócz znaku końca wiersza np. **a.c** pasuje do: //aac//, //abc//, ale nie pasuje do //ac//. 
-  * Nawias kwadratowy pozwala na określenie listy, zakresu znaków np. a[abc]c pasuje do napisów zawierających podciągi: //aac//, //abc//, //acc// - czyli pomiędzy znakami **a** i **c** może wystąpić tylko i wyłącznie jeden znak z podanych w nawiasie. **Uwaga**, należy zauważyć że powyższe wyrażenie pasuje również do: //aabc//, //acccc//, itp. Powyższe wyrażenie jest równoznaczne z **a[a-c]c** poprzez zdefiniowane zakresu za pomocą **-** myślnika. Istnieje także możliwość listowania zakresów: **[a-z0-9]** - oznacza dowolną małą literę od **a** do **z** lub dowolną cyfrę. 
-  * Negacja zakresu ^. Znak ^ umieszczony jako pierwszy wewnątrz nawiasu kwadratowego oznacza jego negację np. **[^a-c]** oznacza wszystkie znaki oprócz **a**, **b**, **c**. 
-  * Znak ^ ma także drugie znaczenie (żeby nie było tak prosto ^_^). Oznacza początek łańcucha znaków, czyli  **^ab** określa wszystkie łańcuchy znaków rozpoczynające się od **ab** np. //​**ab**akus//,​ natomiast nie pasuje do np: //żaba//. 
-  * Podobne znaczenie do ^ ma znak **$** oznaczający koniec łańcucha znaków. 
-  * Okrągłe nawiasy () służą do grupowania części wyrażeń (wykorzystywane do np. określania liczby powtórzeń danego wzorca). 
-  * Powtórzenia:​ liczba powtórzeń określa ilość wystąpienia danego wzorca w badanym łańcuchu znaków. Liczbę powtórzeń możemy zdefiniować w następujący sposób: 
-    * Gwiazdka * - zero lub więcej wystąpień poprzedzającego ją znaku np: **a*** pasuje do //ab//, //aab//, //bab//, //baaab//, ale też do: //b//. 
-    * Plus + - co najmniej jedno wystąpienie poprzedzającego znaku np: **a+** pasuje do //ab//, //aab//, //bab//, //baaab//, ale **nie** do: //b//. 
-    * Znak zapytania ? po symbolu oznacza najwyżej jedno (być może zero) wystąpienie poprzedzającego wyrażenia. 
-    * Nawias klamrowy {} pozwala na dokładne określenie minimalnej i maksymalnej liczby powtórzeń:​ 
-      * {2,5} - minimalnie 2 a maksymalnie 5, 
-      * {3} - dokładnie 3 razy, 
-      * {5,} - co najmniej 5 razy, 
-      * {,6} - co najwyżej 6 razy. 
-  * Pionowa kreska (ang. pipeline) | to operator OR np. jeśli napiszemy a|b|c oznacza to, że w danym wyrażeniu może wystąpić a lub b lub c. 
-  * Jeżeli chcemy użyć jednego ze znaków kontrolnych jako zwykłego to poprzedzamy go backslash-em **\** np: **^\$** definiuje wszystkie łańcuchy znaków rozpoczynające się od znaku dolara ''​$''​. 
- 
- 
- 
-==== Przykłady ==== 
-=== Kod pocztowy === 
-Polski kod pocztowy składa się z pięciu cyfr i myślnika wstawionego po drugiej cyfrze. Przy pomocy wyrażeń regularnych wzorzec kodu pocztowego może być zdefiniowany następująco:​ 
-  * **^[0-9][0-9]-[0-9][0-9][0-9]$** 
-  * **^[0-9]{2}-[0-9]{3}$** 
- 
-=== Liczby dużego lotka === 
-W dużym lotku losowane są liczby od 1 do 49. Przy pomocy wyrażenia regularnego można sprawdzić czy dana liczba może być wylosowana w dużym lotku. Należy wyrażenia zdefiniować następująco:​ 
-  * **^[1-4]?​[0-9]{1}$** 
-  * **^[1-4]{,​1}[0-9]{1}$** 
- 
-=== Adres MAC === 
-Adres MAC jest 48-bitowym numerem karty sieciowej. Najczęściej zapisuje się go w postaci heksadecymalnej. Po każdych dwóch znakach może występować (ale nie musi) separator (najczęściej są to: dwukropek, myślnik, spacja). Przykładowy format adresu MAC to: 
-  * 1F:​34:​C6:​78:​90:​AB 
-  * 1F-34-C6-78-90-ab 
-  * 1f 34 c6 78 90 AB 
-  * 1F34C67890AB 
-Wyrażenie regularne akceptujące powyższe zapisy może być zdefiniowane następująco:​ 
-  - **[A-Fa-f0-9]{2}** - pierwsze dwa znaki (8 bitów bez separatora),​ 
-  - **[-: ]?** - separatory występujące co najwyżej jeden raz, 
-  - **[A-Fa-f0-9]{2}** - kolejne części adresu (ostatnie 40 bitów) 
-  - Wyrażenie składające się z wyr. 2 i 3 trzeba powtórzyć 5 razy: **([-: ]?​[A-Fa-f0-9]{2}){5}** 
-  - Czyli całość może wyglądać następująco:​ **^[A-Fa-f0-9]{2}([-:​ ]?​[A-Fa-f0-9]{2}){5}$** 
- 
-===== SED ===== 
-  * ang. **S**tream **ED**itor - edytor strumieniowy. 
-  * Pomimo swej prostoty umożliwia wykonanie złożonych operacji na łańcuchach znaków. 
-  * Program przyjmuje polecenia do wykonania z pliku lub z wiersza poleceń (jak zdefinować instrukcje do wykonania z linii poleceń a jak z pliku? - manual). 
-  * Program wczytuje dane wejściowe linia po linii i **dla każdej linii wykonuje wszystkie** instrukcje do wykonania!!! 
- 
-===== AWK ===== 
-  * Nazwa pochodzi od pierwszych liter nazwisk jego autorów: //Alfreda V. **A**ho, Petera **W**einbergera i Briana **K**ernighana//​ 
-  * Jest to program interpretujący język skryptowy, służący do przetwarzania wyrażeń regularnych. 
-  * Składnia języka jest bardzo podobna do składni języka C. 
-  * Program wczytuje dane wejściowe rekord po rekordzie i dla każdego rekordu wykonuje wszystkie polecenia. 
- 
- 
-===== Ćwiczenia ===== 
-==== SED ==== 
- 
-Przeczytać manual do programu. Zwrócić uwagę na polecenia, ich składnię oraz sposób adresacji poleceń. 
- 
-  - Wyświetlić plik **/​etc/​passwd** przy pomocy //sed//. 
-  - Zamienić separator - dwukropek - w pliku ''/​etc/​passwd''​ na spację. 
-  - Wyświetlić **tylko** loginy użytkowników zapisanych w pliku ''/​etc/​passwd''​ 
-  - Wyświetlić 4, 7, 10 i 13 linię pliku ''/​etc/​passwd''​ 
-  - Wyświetlić określone przedziałem (np. od 3. do 5. włącznie) linie pliku ''/​etc/​passwd''​. 
-  - Wyświetlić linie pliku ''/​etc/​passwd''​ opisujące osoby mające login zaczynający się na '​z'​. 
-  - Wyświetlić linie pliku ''/​etc/​passwd''​ opisujące osoby mające login zaczynający się na '​w'​ lub '​z'​. 
-  - Jak przy pomocy sed zaimitować polecenie ''​grep -v''?​ np. dla frazy '​lo'​ (''​grep -v lo /​etc/​networks''​) 
-  - Jak zamienić w pliku wszystkie słowa ''​root''​ na twój login (przetestuj na pliku ''/​etc/​aliases''​)?​ 
-  - Jak zamienić słowo '​root'​ na twój login w pliku, ale tylko w wierszach, w których występuje '​www'?​ A jak tam gdzie nie występuje? 
-  - Jak usunąć z pliku puste linie? ​ 
-  - Jak zamienić przy pomocy sed wszystkie litery '​r'​ na '​k'?​ 
-  - W jaki sposób zakodować szyfrem ROT13 plik przy pomocy sed (szyfr zamienia litery na występujące 13 liter dalej, np. a<​->​n,​ b<​->​o,​ itd.)? 
-  - Przy pomocy polecenia sed zakomentuj linijkę link-local w pliku ''/​etc/​networks''​. 
-  - 8-o W jaki sposób przy użyciu sed wstawić kolumnę X po pierwszym znaku wiersza (dodatkowy znak X w każdym wierszu)? A jak po piątym? 
-  - Jak przy pomocy sed powtórzyć 3 razy pierwsze dwie litery każdego wiersza w pliku? 
-  - Wylistuj wszystkie wiersze pliku ''/​etc/​mime.types''​ zaczynające się od ''​video''​ i wyświetl ich numer. 
-  - Napisz polecenie sed imitujące polecenie ''​cut -d: -f2''​. 
-  - W jaki sposób zmienić kolejność słów (np. w pliku ''/​etc/​aliases''​)?​ \\ Jest: ''​news:​ root''​ \\ Zrób: ''​root:​ news''​ 
-  - 8-o Napisz polecenie sed imitujące ''​cat -n''​. 
-  - 8-o Napisać **skrypt** programu //sed// który ustawi powłokę startową wszystkim użytkownikom grupy //is1// (folder domowy w katalogu //is1//) na ''/​bin/​tcsh''​. Skrypt ma wydrukować całą zawartość zmienionego pliku na ekranie wraz z zaznaczeniem zmienionych linii - tak jak jest to przedstawione poniżej.<​code>​ 
----------------------------- 
-linia w której nastąpiła zmiana powłoki 
----------------------------- 
-</​code>​ 
-  - 8-o Napisać **skrypt** programu //sed// wyświetlający linię zawarte w pliku ''/​etc/​passwd''​ w odwrotnej kolejności. 
- 
-==== AWK ==== 
-=== Ćwiczenia === 
-  - Przeczytać manual do programu zwrócić uwagę na: 
-    * wbudowane zmienne, 
-    * wbudowane funkcje, 
-    * wbudowane instrukcje sterujące. 
-  - Jak //awk// interpretuje spacje? 
-  - Co określają następujące zmienne: ''​FS'',​ ''​RS'',​ ''​NF'',​ ''​NR'',​ ''​OFS'',​ ''​ORS''?​ 
-  - Kiedy wykonywane są instrukcje zawarte w blokach ''​BEGIN''​ oraz ''​END''​ w przypadku kiedy zródło danych składa się z wielu plików? 
-  - Zapisać dowolną stronę internetową (może być także ta) w formacie HTML. Wyświetlić jej zawartość przy pomocy polecenia //cat// a następnie przy pomocy programu //awk// usunąć wszystkie znaczniki HTML z treści. Rezultat należy wyświetlić na ekranie. 
-  - Do powyższego zadania dopisać element filtru, który usunie wszystkie puste linie, oraz te które posiadają tylko białe znaki. 
- 
-=== Zadania === 
-\\ 
-**8-) 8-) 8-) Zadanie1** \\ 
- \\ 
-Przeanalizować poniższy skrypt (plik **userlist**):​ 
-<​code>​ 
-#!/bin/sh 
- 
-who | awk '​{print $1}' | sort | uniq | xargs -i"​{}"​ grep -e "​^{}:"​ /etc/passwd | awk -f awkuserlist 
-</​code>​ 
-oraz plik **awkuserlist** (skrypt programu //awk//) który jest w nim wykorzystany:​ 
-<​code>​ 
-BEGIN { 
-    FS=":"​ 
-    print "<​xml version="​1.0">";​ 
-} 
-{ 
-    match($5, "^[^, ]*"); 
-    imie=substr($5,​ RSTART, RLENGTH); 
-    match($5, " [^, ]*"); 
-    nazwisko=substr($5,​ RSTART+1, RLENGTH-1); 
-    login=$1; 
-    uid=$3; 
-    gid=$4; 
-    home=$6; 
-    shell=$7; 
-    print "<​osoba>";​ 
-    print "<​imie>"​imie"</​imie>";​ 
-    print "<​nazwisko>"​nazwisko"</​nazwisko>";​ 
-    print "<​login>"​login"</​login>";​ 
-    print "<​uid>"​uid"</​uid>";​ 
-    print "<​gid>"​gid"</​gid>";​ 
-    print "<​home>"​home"</​home>";​ 
-    print "<​shell>"​shell"</​shell>";​ 
-    print "</​osoba>";​ 
-} 
-END { 
-    print "</​xml>";​ 
-} 
-</​code>​ 
-  * Jaki jest rezultat wykonania skryptu **userlist** 
-  * Dopisać skrypt programu //awk// który przeanalizuje strumień wyjściowy skryptu **userlist** i przekształci go w następujący sposób: 
-  * Format wejściowy: 
-<code xml> 
-<​osoba>​ 
-     <​dana1>​wartosc1</​dana1>​ 
-     <​dana2>​wartosc2</​dana2>​ 
-     <​dana3>​wartosc3</​dana3>​ 
-     <​dana4>​wartosc4</​dana4>​ 
-</​osoba>​ 
-</​code>​ 
-  * Format wyjściowy: 
-<​code>​ 
-------------------------------------------- 
-dana1: wartosc1 
-dana2: wartosc2 
-dana3: wartosc3 
-dana4: wartosc4 
-------------------------------------------- 
-</​code>​ 
-  * Przykład: 
-  * Dla wejścia: 
-<code xml> 
-<​osoba>​ 
-     <​imie>​Jan</​imie>​ 
-     <​nazwisko>​Kowalski</​nazwisko>​ 
-     <​login>​jkowalski</​login>​ 
-     <​uid>​1</​uid>​ 
-     <​gid>​1</​gid>​ 
-     <​home>/​home/​users/​jkowalski</​home>​ 
-     <​shell>/​bin/​bash</​shell>​ 
-     <​miasto>​Kraków</​miasto>​ 
-</​osoba>​ 
-</​code>​ 
-  * Skrypt powinien wygenerować wyjście: 
-<​code>​ 
-------------------------------------------- 
-imie: Jan 
-nazwisko: Kowalski 
-login: jkowalski 
-uid: 1 
-gid: 1 
-home: /​home/​users/​jkowalski 
-shell: /bin/bash 
-miasto: Kraków 
-------------------------------------------- 
-</​code>​ 
- 
-\\  
-** 8-) 8-) 8-) Zadanie 2** \\ 
- \\ 
-**BibTeX** to narzędzie służące do formatowania bibliografii. 
-Operuje ono na danych zawartych w plikach o rozszerzeniu "​bib"​ 
-zawierających dane bibliograficzne. 
-Przykład pliku: {{:​pl:​dydaktyka:​unix:​publikacje.bib.txt|}}. 
- 
-Poszczególne wpisy bibliograficzne mają następującą postać: 
-<​code>​ 
-@rodzaj{klucz,​ 
-  author = {wartość},​ 
-  title = {wartość},​ 
-  year = wartość, 
-  other = {wartość} 
-} 
-</​code>​ 
-Zadanie polega na stworzeniu skryptu ''​bash'', ​ 
-który przy użyciu ''​awk''​ wybierze z pliku tylko te wpisy bibliograficzne, ​ 
-które odpowiadają zapytaniu użytkownika. 
-Tzn. skrypt zapisany w pliku ''​szukaj''​ powinien obsługiwać 
-następujące opcje (-a, -t, -k): 
-  * ''​./​szukaj -a Nalepa''​ - wyszuka wszystkie publikacje autorstwa Nalepy (te wpisy bibtexowe, w których polu ''​author''​ występuje ''​Nalepa''​),​ 
-  * ''​./​szukaj -t slowo''​ - wyszuka wszystkie publikacje zawierające w tytule ciąg ''​slowo'',​ 
-  * ''​./​szukaj -k slowo''​ - wyszuka wszystkie publikacje zawierające ciąg ''​slowo''​ w dowolnym polu. 
- 
-\\  
-** 8-) 8-) 8-) Zadanie 3** \\ 
- \\ 
-Napisz skrypt programu awk który policzy i wyświetli średnią ocen dla każdego studenta. 
-Lista studentów oraz ocen jest zapisana w pliku, którego nazwę podajemy jako parametr uruchomienia programu awk (nazwa pliku nie może być zakodowana wewnątrz skryptu). 
-Format pliku zawierającego listę studentów oraz ocen jest następujący:<​code>​ 
-login_1:​ocena_1,​ocena_2,​ocena_3 
-login_2:​ocena_1,​ocena_2,​ocena_3,​ocena_4</​code>​ 
-Należy przyjąć następujące założenia:​ 
-  - ''​login_n''​ - jest loginem danego studenta. 
-  - ''​login_n''​ - istnieje w pliku ''/​etc/​passwd''​. 
-  - Liczba studentów nie jest określona, definiuje ją tylko i wyłącznie liczba linii w pliku. 
-  - Plik zawiera tylko linie w powyższym formacie - przyjmujemy jako aksjomat i nie weryfikujemy tej kwestii. 
-  - ''​ocena_n''​ - oznacza ocenę, liczbę ze zbioru ''​{2.0,​ 3.0, 3.5, 4.0, 4.5, 5.0}''​ (nie ma przymusu sprawdzania poprawności - przyjmujemy że oceny są wpisane poprawnie). 
-  - Liczba ocen dla każdego studenta nie jest określona i może być różna. 
-  - Spacje w pliku nie wpływają na sposób jego przetwarzania. 
-Jako rezultat, skrypt powinien wyświetlić informację o uzyskanej średniej ocenie przez każdego studenta w następującym formacie:<​code>​Srednia ocena dla Imie Nazwisko wynosi: X</​code>​ 
-gdzie: 
-  - ''​Imie Nazwisko''​ - oznaczają odpowiednio imię i nazwisko studenta pobrane z pliku ''/​etc/​passwd''​ (uwaga: nie login jak to jest w pliku wejściowym). 
-  - ''​X''​ - wartość średniej oceny z dokładnością do dwóch miejsc po przecinku. 
-Napisany skrypt nie może używać żadnych poleceń zewnętrznych.\\ 
-Przykłady plików: {{:​pl:​dydaktyka:​unix:​input.txt|wejściowego}} oraz {{:​pl:​dydaktyka:​unix:​output.txt|wyjściowego}}. 
- 
-===== Dla zainteresowanych ===== 
- 
-  * Artykuł o //sed//: [[http://​www.ibm.com/​developerworks/​linux/​library/​l-sed1.html|część 1]], [[http://​www.ibm.com/​developerworks/​linux/​library/​l-sed2.html|część 2]], [[http://​www.ibm.com/​developerworks/​linux/​library/​l-sed3.html|część 3]]. 
-  * Artykuł o //awk//: [[http://​www.ibm.com/​developerworks/​linux/​library/​l-awk1.html|część 1]], [[http://​www.ibm.com/​developerworks/​linux/​library/​l-awk2.html|część 2]], [[http://​www.ibm.com/​developerworks/​linux/​library/​l-awk3.html|część 3]]. 
pl/dydaktyka/unix/lab_sed_awk.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0