Table of Contents

SED i Awk

Przygotuj się do laboratorium

Wiedza

1. SED i Awk

SED:

AWK:

2. Wyrażenia regularne

Definiowanie wyrażeń regularnych:

Przykłady:

Ćwiczenia

I. Wyrażenia regularne

Jeżeli chcesz pobawić się wyrażeniami regularnymi to warto odwiedzić: Regex Crossword :-)

Jeżeli po prostu chcesz przetestować i zrozumieć wyrażenia regularne to w sieci dostępnych jest wiele webowych serwisów, które pozwalają na wpisanie wyrażenia, wyjaśniają jego poszczególne elementy i wyświetlają dopasowania na tekście, np.:

II. SED

Przeczytaj manual do programu. Zwróć uwagę na polecenia, ich składnię oraz sposób adresacji poleceń.

  1. Wyświetl plik /etc/passwd przy pomocy sed.
  2. Zamień separator - dwukropek - w pliku /etc/passwd na spację.
  3. Wyświetl tylko loginy użytkowników zapisanych w pliku /etc/passwd
  4. Wyświetl 4, 7, 10 i 13 linię pliku /etc/passwd
  5. Wyświetl określone przedziałem (np. od 3. do 5. włącznie) linie pliku /etc/passwd.
  6. Wyświetl linie pliku /etc/passwd opisujące osoby mające login zaczynający się na 'z'.
  7. Wyświetl linie pliku /etc/passwd opisujące osoby mające login zaczynający się na 'w' lub 'z'.
  8. Jak przy pomocy sed zaimitować polecenie grep -v? np. dla frazy 'lo' (grep -v lo /etc/networks)
  9. Jak zamienić w pliku wszystkie słowa root na twój login (przetestuj na pliku /etc/passwd)?
  10. 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?
  11. Jak usunąć z pliku puste linie?
  12. Jak zamienić przy pomocy sed wszystkie litery 'r' na 'k'?
  13. 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.)?
  14. Przy pomocy polecenia sed zakomentuj linijkę link-local w pliku /etc/networks.
  15. 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?
  16. Jak przy pomocy sed powtórzyć 3 razy pierwsze dwie litery każdego wiersza w pliku?
  17. Wylistuj wszystkie wiersze pliku /etc/mime.types zaczynające się od video i wyświetl ich numer.
  18. Napisz polecenie sed imitujące polecenie cut -d: -f2.
  19. Napisz polecenie sed imitujące cat -n.
  20. Napisać skrypt programu sed który ustawi powłokę startową na /bin/tcsh dla wszystkich użytkowników posiadającym folder domowy /nonexistent (zmodyfikuje odpowiednio plik /etc/passwd). Skrypt ma wydrukować całą zawartość zmienionego pliku na ekranie wraz z zaznaczeniem zmienionych linii - tak jak jest to przedstawione poniżej:
    ----------------------------
    linia w której nastąpiła zmiana powłoki
    ----------------------------
  21. Napisać skrypt programu sed wyświetlający linię zawarte w pliku /etc/passwd w odwrotnej kolejności.

III. AWK

  1. Przeczytać manual do programu zwrócić uwagę na:
    • wbudowane zmienne,
    • wbudowane funkcje,
    • wbudowane instrukcje sterujące.
  2. Jak awk interpretuje spacje?
  3. Co określają następujące zmienne: FS, RS, NF, NR, OFS, ORS?
  4. Kiedy wykonywane są instrukcje zawarte w blokach BEGIN oraz END w przypadku kiedy zródło danych składa się z wielu plików?
  5. 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.
  6. Do powyższego zadania dopisać element filtru, który usunie wszystkie puste linie, oraz te które posiadają tylko białe znaki.
  7. Zadanie1:
    1. Przeanalizować poniższy skrypt (plik userlist):
      #!/bin/sh
       
      who | awk '{print $1}' | sort | uniq | xargs -i"{}" grep -e "^{}:" /etc/passwd | awk -f awkuserlist

      oraz plik awkuserlist (skrypt programu awk) który jest w nim wykorzystany:

      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>";
      }
    2. Jaki jest rezultat wykonania skryptu userlist?
      • Uwaga, na serwerze spk ten skrypt nie działa (dane użytkowników nie są przechowywane w /etc/passwd) - w takiej sytuacji zastąp fragment generujący aktualną listę obecności (who | awk '{print $1}' ) przez fragment, który wprost zadaje przykładowe loginy z /etc/passwd (np. echo -e 'root\ngames\nman' )
    3. 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:
        <osoba>
             <dana1>wartosc1</dana1>
             <dana2>wartosc2</dana2>
             <dana3>wartosc3</dana3>
             <dana4>wartosc4</dana4>
        </osoba>
      • Format wyjściowy:
        -------------------------------------------
        dana1: wartosc1
        dana2: wartosc2
        dana3: wartosc3
        dana4: wartosc4
        -------------------------------------------
      • Przykład:
        • Dla wejścia:
          <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>
        • Skrypt powinien wygenerować wyjście:
          -------------------------------------------
          imie: Jan
          nazwisko: Kowalski
          login: jkowalski
          uid: 1
          gid: 1
          home: /home/users/jkowalski
          shell: /bin/bash
          miasto: Kraków
          -------------------------------------------
  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.
    • Poszczególne wpisy bibliograficzne mają następującą postać:
      @rodzaj{klucz,
        author = {wartość},
        title = {wartość},
        year = wartość,
        other = {wartość}
      }
    • Zadanie polega na stworzeniu skryptu bash o nazwie szukaj, który przy użyciu awk wybierze z pliku publikacje.bib tylko te wpisy bibliograficzne, które odpowiadają zapytaniu użytkownika. Skrypt powinien obsługiwać trzy 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.
  9. 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
    • Założenia:
      1. login_n - jest loginem danego studenta
      2. Liczba studentów nie jest określona, definiuje ją tylko i wyłącznie liczba linii w pliku.
      3. Plik zawiera tylko linie w powyższym formacie - przyjmujemy jako aksjomat i nie weryfikujemy tej kwestii.
      4. 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).
      5. Liczba ocen dla każdego studenta nie jest określona i może być różna.
      6. 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 Login: X

      gdzie X to wartość średniej oceny z dokładnością do dwóch miejsc po przecinku.

    • Skrypt powinien być w całości wykonywany przez awk - nie powinien używać żadnych poleceń zewnętrznych.
    • Przykład:
      • Dla wejścia:
        spock:4.0, 4.5, 4.5, 5.0, 5.0, 2.0
        scotty : 4.5, 3.0, 4.0, 3.5, 5.0, 2.0, 5.0, 5.0, 4.5
        sulu:3.5     ,  3.0, 5.0, 4.5, 2.0, 3.5, 4.5, 3.0, 2.0, 4.5, 4.0, 5.0, 2.0, 5.0, 3.5, 4.5, 5.0, 5.0, 4.5, 4.0, 5.0, 3.5, 5.0, 5.0, 5.0, 4.5, 5.0, 3.5, 3.5, 4.0, 4.0, 3.5, 4.0, 5.0, 3.0, 3.0
        chekov:2.0, 4.5, 5.0     , 5.0, 4.0, 5.0, 5.0, 2.0, 3.0, 4.5
        yar:3.0, 2.0, 5.0,   2.0, 3.0, 5.0, 3.0, 4.5, 5.0, 5.0, 5.0, 5.0, 4.5, 3.5, 2.0, 3.5, 4.0, 3.5, 2.0
        enterprise:3.5, 2.0, 3.0, 3.0   
        riker    :   3.0, 3.0, 3.0, 2.0, 4.0, 2.0, 5.0, 5.0, 4.0, 2.0, 5.0, 3.5, 3.0, 2.0, 2.0, 4.5, 4.5, 5.0, 3.5, 4.5, 3.5, 4.5, 3.0, 5.0, 5.0, 3.0, 3.5, 3.5, 5.0, 5.0, 4.5, 3.0, 2.0, 5.0, 5.0, 3.0, 4.5, 3.0
        picard : 3.0  , 3.0, 3.0, 4.0, 3.5, 4.0, 3.0, 5.0, 5.0, 4.5, 4.0
        laforge:    4.0, 4.5, 5.0, 3.5, 4.5, 4.5, 4.5, 2.0, 3.0, 3.0, 3.5
        yoda:3.5, 4.0, 4.5, 4.5, 2.0
        worf    :2.0, 5.0, 4.0, 4.0, 3.5, 4.5    , 5.0
        starfleet:5.0, 4.5, 3.5, 3.0, 4.0, 3.0, 4.0, 2.0, 3.0, 2.0, 5.0, 2.0, 3.5, 4.5, 4.5, 4.0, 3.0, 3.0, 3.5, 3.0, 3.0, 3.5, 2.0, 3.0, 3.5, 4.0, 4.5, 5.0, 3.5, 5.0, 3.5, 3.5, 3.5, 3.0, 5.0, 3.5, 4.5, 3.0, 4.5, 4.5, 5.0, 4.5, 3.5, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0
        kirk:4.0, 3.0, 5.0, 5.0, 5.0, 2.0, 2.0, 4.0
        uhura   :   3.5, 2.0, 5.0, 5.0, 5.0   , 4.0, 5.0, 5.0, 4.0, 4.5, 3.0, 3.0, 3.5, 4.0, 3.5, 4.0, 5.0, 4.0, 3.0, 4.5, 4.5, 5.0, 3.5, 4.0, 4.5, 5.0, 5.0, 5.0, 3.0, 5.0, 4.0, 4.0, 5.0, 4.5, 5.0, 3.0, 4.0, 5.0, 4.5, 2.0, 4.5, 5.0, 4.0, 3.0, 3.0, 4.5, 2.0, 2.0, 3.0, 3.5, 5.0
      • Skrypt powinien wygenerować wyjście:
        Srednia ocen dla spock: 4.17
        Srednia ocen dla scotty: 4.06
        Srednia ocen dla sulu: 4.01
        Srednia ocen dla chekov: 4
        Srednia ocen dla yar: 3.71
        Srednia ocen dla enterprise: 2.88
        Srednia ocen dla riker: 3.72
        Srednia ocen dla picard: 3.82
        Srednia ocen dla laforge: 3.82
        Srednia ocen dla yoda: 3.70
        Srednia ocen dla worf: 4
        Srednia ocen dla starfleet: 3.68
        Srednia ocen dla kirk: 3.75
        Srednia ocen dla uhura: 4.03