To jest stara wersja strony!


SED i AWK

Do przygotowania

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
  • 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. gitara (ale nie Gitara), zagadka, log.
  • Wyrażenie ba opisuje wszystkie łańcuchy znaków zawierające podciąg ba np. baca, zabawa, żaba.
  • 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. abakus, 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. Stream EDitor - 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. Aho, Petera Weinbergera i Briana Kernighana * 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 nazwy 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 'q' 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ę default 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: 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-) 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:

login_1:ocena_1,ocena_2,ocena_3
login_2:ocena_1,ocena_2,ocena_3,ocena_4

Należy przyjąć następujące założenia:

  1. login_n - jest loginem danego studenta.
  2. login_n - istnieje w pliku /etc/passwd.
  3. Liczba studentów nie jest określona, definiuje ją tylko i wyłącznie liczba linii w pliku.
  4. Plik zawiera tylko linie w powyższym formacie - przyjmujemy jako aksjomat i nie weryfikujemy tej kwestii.
  5. 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).
  6. Liczba ocen dla każdego studenta nie jest określona i może być różna.
  7. 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:

Srednia ocena dla Imie Nazwisko wynosi: X

gdzie:

  1. Imie Nazwisko - oznaczają odpowiednio imię i nazwisko studenta pobrane z pliku /etc/passwd (uwaga: nie login jak to jest w pliku wejściowym).
  2. 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: wejściowego oraz wyjściowego.

Dla zainteresowanych

pl/dydaktyka/unix/lab_sed_awk.1384344306.txt.gz · ostatnio zmienione: 2019/06/27 15:55 (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