Provided by: manpages-pl_20060617-1_all bug

NAZWA

       textutils - opis pakietu narzędzi tekstowych GNU

OD TŁUMACZA

       Podręczniki  man  dla  narzędzi  tekstowych  GNU  nie są już rozwijane.
       Niniejsza strona podręcznika powstała jako tłumaczenie, używanej  przez
       twórców  jako  podstawowej,  dokumentacji formatu info.  W pliku, który
       czytasz umieszczono część dokumentacji dotyczącą wspólnych cech i opcji
       programów oraz informacje, które z różnych przyczyn nie znalazły się na
       stronach opisujących poszczególne polecenia pakietu.  Szczegółowe opisy
       samych poleceń znajdziesz we właściwych, osobnych stronach podręcznika.

WSTĘP

       Niniejszy podręcznik opisuje zestaw narzędzi tekstowych  GNU  w  wersji
       2.0.

       Jak  i  inne  podręczniki  pakietu,  i  ten  nie jest wyczerpujący: nie
       usiłowano  wyjaśnić  podstawowych  pojęć  w   sposób   odpowiedni   dla
       nowicjuszy.  Zatem,  jeśli  jesteś zainteresowany, włącz się, proszę, w
       udoskonalanie go. Skorzysta na tym cała wspólnota GNU.

       Narzędzia tekstowe GNU są w większości zgodne ze standardem POSIX.2.

       Błędy proszę zgłaszać, w  jęz.angielskim,  do  <bug-fileutils@gnu.org>.
       Pamiętaj,  by  zamieścić  numer  wersji,  architekturę  maszyny,  pliki
       wejściowe i inne informacje potrzebne do powielenia błędu:  wprowadzane
       znaki,  czego  się  spodziewałeś, co otrzymałeś i dlaczego jest to źle.
       Pliki diff są mile widziane, ale proszę dołączyć również opis problemu,
       gdyż czasem ciężko jest wyciągnąć wnioski.

       Podręcznik  ten  powstał  pierwotnie  na  bazie  uniksowych  stron  man
       napisanych  przez  Davida  MacKenzie  i  aktualizowanych   przez   Jima
       Meyeringa.  Autorytatywną  dokumentacją  jest  obecnie  dokumentacja  w
       formacie info;  strony  man  nie  są  już  rozwijane  i  aktualizowane.
       Franc,ois  Pinard  wykonał  wstępną  konwersję do formatu Texinfo. Karl
       Berry wykonał indeksy, trochę reorganizacji i edycji wyników.   Richard
       Stallman wniósł swój zwykły nieoceniony wgląd w całość procesu.

ZAWARTOŚĆ PAKIETU

       Obecnie  pakiet  narzędzi  tekstowych  GNU  zawiera  dwadzieścia  kilka
       programów:

   Wypisywanie całości plików
           cat         łączenie i wypisywanie plików
           tac         łączenie i wypisywanie odwróconych plików
           nl          numerowanie linii i wypisywanie plików
           od          wypisywanie plików w formacie ósemkowym i innych

   Formatowanie zawartości plików
           fmt         reformatowanie akapitów tekstu
           pr          stronicowanie i kolumnowanie plików do wydruku
           fold        zawijanie linii wejściowych do zadanej szerokości

   Wypisywanie części plików
           head        wypisywanie początku plików
           tail        wypisywanie końcówki plików
           split       podział pliku na części stałej wielkości
           csplit      podział pliku na części zależne od kontekstu

   Podsumowywanie plików
           wc          wypisywanie liczby bajtów, słów i linii
           sum         wypisywanie sumy kontrolnej i liczby bloków
           csum        wypisywanie sumy CRC liczby bloków
           md5sum      wypisywanie lub sprawdzanie skrótu danych

   Sortowanie i działania na plikach posortowanych
           sort        sortowanie plików tekstowych
           uniq        pozostawianie unikalnych linii w pliku
           comm        porównywanie dwu posortowanych plików liniami
           ptx         tworzenie indeksu permutacyjnego zawartości pliku
           tsort       sortowanie topologiczne

   Działania na polach wewnątrz linii
           cut         wypisywanie wybranych części linii
           paste       zlepianie linii plików
           join        łączenie linii według wspólnego pola

   Działania na znakach
           tr          zamiana, ściskanie, usuwanie znaków
           expand      zamiana tabulacji na spacje
           unexpand    zamiana spacji na tabulacje

OPCJE WSPÓLNE

       Pewne opcje dostępne są we wszystkich opisywanych programach  (naprawdę
       powinien je przyjmować każdy z programów GNU).

       --help Wyświetla  informację  o  stosowaniu programu i listę wszystkich
              dostępnych opcji, pomyślnie kończy pracę.

       --version
              Wyświetla numer wersji programu i pomyślnie kończy pracę.

Otwarcie skrzynki narzędziowej z programami

       Ten rozdział pierwotnie pojawił się w 'Linux Journal', volume 1, nr  2,
       na kolumnie `What's GNU?'. Został napisany przez Arnolda Robbinsa.

   Wprowadzenie
       W  tym  miesiącu  artykuł jest tylko ubocznie związany z Projektem GNU,
       gdyż opisuje kilka narzędzi GNU obecnych w systemie Linux i sposoby, na
       jakie  możesz  z  nich  korzystać.  Faktycznie artykuł jest o filozofii
       "Narzędzi programowych" w rozwijaniu i wykorzystywaniu programów.

       Filozofia narzędzi programowych była ważnym i  integralnym  pojęciem  w
       początkowym  projekcie  i  rozwoju  Uniksa  (którego  Linux  i  GNU  są
       zasadniczo klonami). Niestety, przy współczesnym nacisku  intersieci  i
       błyskotliwych  GUI, wydaje się, że idea ta spadła na pobocze. To wstyd,
       ponieważ zapewnia ona potężny  model  myślowy  do  rozwiązywania  wielu
       rodzajów problemów.

       Sporo  ludzi  nosi  w kieszeniach spodni szwajcarski scyzoryk. Scyzoryk
       jest  wygodnym  narzędziem:  ma  kilka  ostrzy,   śrubokręt,   pincetę,
       wykałaczkę,  zestaw  gwoździ,  korkociąg i może kilka innych rzeczy. Do
       codziennych drobnych, różnorodnych zadań, gdzie  potrzebujesz  prostego
       narzędzia ogólnego zastosowania, jest właśnie tym, o co chodzi.

       Z  drugiej  strony,  doświadczony  cieśla  nie buduje domu scyzorykiem.
       Zamiast tego ma skrzynkę wypchaną specjalizowanymi narzędziami --  jest
       tam piła, młotek, śrubokręt, strug i tak dalej. I dokładnie wie kiedy i
       gdzie użyć każdego z narzędzi. Nie przyłapałbyś go na wbijaniu  gwoździ
       rękojeścią śrubokrętu.

       Konstruktorzy  Uniksa w Bell Labs byli całkiem zawodowymi programistami
       i wyszkolonymi naukowcami komputerowymi. Zauważyli, że choć rozwiązanie
       wszystko-w-jednym  może  przyciągać użytkownika, gdyż ma on tylko jeden
       program do korzystania, w praktyce programy takie są

       a. trudne do napisania,

       b. trudne w konserwacji i usuwaniu błędów, oraz

       c. trudne do rozbudowy, przystosowania do nowych sytuacji.

       Uważali,  że  zamiast  tego,  programy  powinny  być   specjalizowanymi
       narzędziami.   Krótko mówiąc, każdy program "powinien robić jedną rzecz
       dobrze". Nie więcej i  nie  mniej.  Takie  programy  są  łatwiejsze  do
       zaprojektowania, napisania i zrozumienia -- robią tylko jedną rzecz.

       Ponadto  zauważyli,  że przy odpowiednim mechanizmie łączenia programów
       całość jest większa od sumy składowych. Wiążąc  kilka  specjalizowanych
       programów możesz zrealizować konkretne zadanie, do którego żaden z nich
       nie był projektowany i osiągnąć to dużo szybciej i łatwiej  niż  pisząc
       dla  niego  specjalizowany program. W dalszej części artykułu zobaczymy
       kilka (klasycznych) tego przykładów. Ważnym dodatkowym punktem było to,
       że  jeśli  jest  to  niezbędne, należy najpierw zrobić narzędzia, które
       będą potrzebne, jeżeli nie  ma  się  jeszcze  odpowiednich  w  skrzynce
       narzędziowej.

   Przekierowanie wejścia/wyjścia
       Mam   nadzieję,   że  jesteś  obeznany  z  podstawami  przekierowywania
       wejścia/wyjścia w powłoce, w szczególności z  pojęciami  "standardowego
       wejścia",  "standardowego  wyjścia"  i  "standardowego  wyjścia  błędów
       (diagnostycznego)". Zwięźle: "standardowe wejście" jest źródłem danych,
       skąd  pochodzą  dane.  Program  nie  musi  wiedzieć  ani dbać o to, czy
       źródłem danych jest plik dyskowy,  klawiatura,  taśma  magnetyczna  czy
       nawet  czytnik kart perforowanych. Podobnie, "standardowe wyjście" jest
       odpływem danych, dokąd dane spływają. Program nie powinien ani wiedzieć
       ani  dbać  o to, gdzie to może być. Programy, które tylko czytają swoje
       standardowe  wejście,  robią  coś  z  tymi  danymi  i  wysyłają  je  na
       standardowe  wyjście, nazywane są "filtrami", przez analogię do filtrów
       w wodociągach.

       W powłoce uniksowej bardzo łatwo jest zestawić potoki  danych:  [tłum.:
       ang.'pipeline' to 'rurociąg' lub, w informatyce, 'potok']

           program_tworzacy_dane | filtr1 | .... | filtrN > koncowe.dane

       Zaczynamy  od  utworzenia  surowych danych pierwotnych. Każdy z filtrów
       stosuje pewne kolejne przekształcenie danych,  aż  wychodząc  z  potoku
       będą one mieć pożądaną postać.

       To  jest  eleganckie  i dobre dla standardowego wejścia i standardowego
       wyjścia.  A gdzie się  tu  pojawia  standardowe  wyjście  błędów?  Cóż,
       pomyślmy o 'filtr1' w powyższym potoku. Co się stanie, jeśli napotka on
       błąd w przyjmowanych danych? Jeżeli  wypisze  komunikat  o  błędzie  na
       standardowe  wyjście,  to  po  prostu  zniknie  on  w potoku wejścia do
       'filtr2' a użytkownik zapewne nigdy go nie zobaczy.  Zatem  programiści
       potrzebują  miejsca, gdzie mogliby wysyłać komunikaty o błędach, tak by
       użytkownik je zauważył. Jest to  standardowe  wyjście  diagnostyczne  i
       zwykle   związane   jest   z  twoją  konsolą  lub  oknem,  nawet  jeśli
       przekierowałeś standardowe wyjście programu gdzieś poza ekran.

       Aby programy filtrujące  mogły  współdziałać,  musi  zostać  uzgodniony
       format  danych.  Najprostszym i najłatwiejszym w wykorzystaniu formatem
       są zwykłe wiersze tekstu. Uniksowe pliki danych są zazwyczaj po  prostu
       strumieniami  bajtów,  o  wierszach zakończonych znakiem LF ASCII (Line
       Feed - wysuw linii), konwencjonalnie w  literaturze  dotyczącej  Uniksa
       nazywanym   "znakiem  nowej  linii"  (newline).  (Jest  to  '\n'  jeśli
       programujesz w C.)  To  format  stosowany  przez  wszystkie  tradycyjne
       programy   filtrujące.   (Wiele  wcześniejszych  systemów  operacyjnych
       wypracowało  środki  i  specjalizowane  programy  do   obsługi   danych
       binarnych.   Unix  zawsze  wystrzegał  się  takich  rzeczy,  zgodnie  z
       filozofią, że najłatwiej jest móc  przeglądać  i  modyfikować  dane  po
       prostu edytorem tekstu.)

       Dobrze,  starczy  wprowadzenia. Przyjrzyjmy się niektórym narzędziom, a
       wtedy zobaczymy jak wiązać je ze sobą na ciekawe  sposoby.  W  dalszych
       rozważaniach  pokażemy  tylko  te  opcje  wiersza  poleceń,  które  nas
       interesują.  Tak jak zawsze powinieneś, dwukrotnie sprawdź dokumentację
       systemową.  Znajdziesz tam pełne opisy.

   Polecenie 'who'
       Pierwszym  programem  jest  polecenie  'who'. Samodzielne, tworzy listę
       aktualnie zalogowanych użytkowników.  Mimo,  że  piszę  to  w  systemie
       jednoużytkownikowym, będziemy udawać, że zalogowanych jest kilka osób:

            $ who
            arnold   console Jan 22 19:57
            miriam   ttyp0   Jan 23 14:19(:0.0)
            bill     ttyp1   Jan 21 09:32(:0.0)
            arnold   ttyp2   Jan 23 20:48(:0.0)

       Znak '$' jest tu zwyczajową zachętą powłoki, po której napisałem 'who'.
       Zalogowane są trzy osoby, w tym ja dwukrotnie. W tradycyjnych systemach
       Unix nazwy użytkowników nigdy nie mają więcej niż osiem znaków. Ta mała
       ciekawostka przyda się później. Wyjście z  'who'  wygląda  ładnie,  ale
       dane nie są aż tak pasjonujące.

   Polecenie 'cut'
       Następnym  programem,  któremu  się  przyglądniemy jest polecenie 'cut'
       (wytnij).  Wycina  ono  kolumny  lub  pola  z  danych  wejściowych.  Na
       przykład,  możemy  nakazać  mu  wypisanie  tylko  nazwy zgłoszeniowej i
       nazwiska z pliku /etc/passwd.  Plik posiada siedem  pól,  rozdzielonych
       dwukropkami:

            arnold:xyzzy:2076:10:Arnold D. Robbins:/home/arnold:/bin/ksh

       Do pobrania pierwszego i piątego pola, użylibyśmy takiego wycinania:

            $ cut -d: -f1,5 /etc/passwd
            root:Operator
            ...
            arnold:Arnold D. Robbins
            miriam:Miriam A. Robbins
            ...

       Z  opcją  '-c',  'cut'  wycina  konkretne  znaki  (tj. kolumny) wierszy
       wejściowych.  To polecenie wygląda na przydatne do filtrowania  danych.

   Polecenie 'sort'
       Następnie przyjrzymy się 'sort'. To jedno z najpotężniejszych poleceń w
       systemie typu uniksowego. Często będziesz go używał przy  konstruowaniu
       różnych  wymyślnych rurociągów. 'sort' czyta i sortuje każdy z podanych
       w wierszu poleceń plików. Następnie scala uporządkowane dane i wypisuje
       na  standardowe  wyjście.  Jeśli w wierszu poleceń nie poda się żadnych
       nazw plików to czyta standardowe  wejście  (w  ten  sposób  robimy  zeń
       filtr). Sortowanie oparte jest na leksykograficznym porządku znaków lub
       kryteriach porządkowania zadanych przez użytkownika.

   Polecenie `uniq'
       Na koniec (przynajmniej na razie), przyglądniemy się programowi 'uniq'.
       Przy  sortowaniu  danych  często  uzyskasz powtórzone wiersze, wiersze,
       które są identyczne. Zazwyczaj potrzebujesz tylko  jednego  wystąpienia
       każdego  z  nich.  Tu  właśnie  pojawia  się  'uniq'. Czyta on ze swego
       standardowego wejścia,  spodziewając  się,  że  jest  ono  posortowane.
       Wypisuje  tylko jeden egzemplarz każdego zduplikowanego wiersza. 'uniq'
       ma kilka opcji. W dalszym ciągu  wykorzystamy  opcję  '-c',  wypisującą
       przed   niepowtarzalnym   wierszem   ile  razy  wystąpił  on  w  danych
       wejściowych.

   Łączenie narzędzi
       Załóżmy  teraz,  że  mamy  system  BBS  z   zalogowanymi   dziesiątkami
       użytkowników.  Zarządzający  chcą,  by operator systemu (SysOp) napisał
       program  tworzący  posortowaną  listę  zalogowanych  użytkowników.   Co
       więcej, nawet jeśli użytkownik jest zalogowany wielokrotnie, jego nazwa
       powinna w wyniku pojawić się tylko raz.

       SysOp mógłby siąść z dokumentacją systemową  i  napisać  program  w  C,
       który  by  to robił. Kosztowałoby to pewnie kilkaset linii kodu i około
       dwu godzin  pisania,  testowania  i  usuwania  błędów.  Jednak,  znając
       narzędzia  programowe,  SysOp  może  zamiast  tego zacząć od utworzenia
       tylko listy zalogowanych użytkowników:

            $ who | cut -c1-8
            arnold
            miriam
            bill
            arnold

       Następnie, posortować listę:

            $ who | cut -c1-8 | sort
            arnold
            arnold
            bill
            miriam

       Na koniec, przepuścić  posortowaną  listę  przez  'uniq',  by  wypielić
       duplikaty:

            $ who | cut -c1-8 | sort | uniq
            arnold
            bill
            miriam

       Polecenie  'sort'  faktycznie  posiada  opcję  '-u',  która robi to, co
       'uniq'.  Jednak 'uniq' ma inne zastosowania, w  których  nie  można  go
       zastąpić przez 'sort -u'.

       SysOp  umieszcza ten potok w skrypcie powłoki i udostępnia go wszystkim
       użytkownikom systemu:

            # cat > /usr/local/bin/listusers
            who | cut -c1-8 | sort | uniq
            ^D
            # chmod +x /usr/local/bin/listusers

       Warto tu zauważyć cztery zalety.  Po  pierwsze,  przy  pomocy  zaledwie
       czterech programów, w jednej linii poleceń, SysOp mógł oszczędzić około
       dwu godzin pracy.  Co  więcej,  potok  powłoki  jest  prawie  tak  samo
       wydajny,  jak  byłby  program  w  C, a o wiele bardziej efektywny jeśli
       chodzi o czas programisty. Czas ludzki jest o wiele kosztowniejszy  niż
       czas  komputera,  a  w naszym współczesnym społeczeństwie, gdzie "nigdy
       nie ma dość czasu by wszystko zrobić", zaoszczędzenie dwu godzin  czasu
       programisty jest nie byle jakim wyczynem.

       Po   drugie,   równie   istotne   jest  podkreślenie,  że  przy  pomocy
       _połączenia_ narzędzi możliwe  jest  wykonanie  specyficznego  zadania,
       nigdy nie przewidywanego przez autorów pojedynczych programów.

       Po  trzecie,  wartościowe  jest  też stopniowe budowanie potoku, jak to
       zrobiliśmy. Pozwala ono na przyglądnięcie się danym  na  każdym  etapie
       przebiegu  potoku, co pomaga uzyskać pewność, że rzeczywiście poprawnie
       używasz narzędzi.

       Na koniec, dzięki zapakowaniu potoku w skrypt powłoki, inni użytkownicy
       mogą  korzystać  z  twojego polecenia, nie musząc pamiętać o zawartości
       tego wymyślnego opakowania. Z  punktu  widzenia  sposobu  uruchamiania,
       skrypty powłoki i skompilowane programy są nierozróżnialne.

       Po  uprzedniej  rozgrzewce,  przypatrzymy  się  dwu  kolejnym, bardziej
       skomplikowanym potokom.  Potrzebujemy dla nich wprowadzić  jeszcze  dwa
       narzędzia.

       Pierwszym jest polecenie 'tr', oznaczające "transliterację".  Polecenie
       'tr'  wymienia  znaki,  działając  na  zasadzie  znak-na-znak.   Zwykle
       stosowane  jest do takich rzeczy jak odwzorowanie dużych liter na małe.

            $ echo ThIs ExAmPlE HaS MIXED case! | tr '[A-Z]' '[a-z]'
            this example has mixed case!

       Interesuje nas kilka opcji:

       -c     działa na dopełnieniu wskazanych znaków, tj.  działania  odnoszą
              się do znaków spoza zadanego zestawu

       -d     usuwa z wyniku znaki określone w pierwszym zestawie

       -s     ściska w wyniku powtórzone znaki w pojedynczy znak.

       Za chwilę będziemy korzystać ze wszystkich trzech opcji.

       Innym  poleceniem,  któremu się przyjrzymy jest 'comm'. Pobiera ono dwa
       posortowane pliki jako dane wejściowe i wypisuje ich wiersze  w  trzech
       kolumnach. Kolumny wynikowe są unikalnymi wierszami z pierwszego pliku,
       unikalnymi wierszami z drugiego pliku i wierszami danych wspólnymi  dla
       obu.   Opcje  '1', '-2' i '3' pomijają odpowiednie kolumny. Nie jest to
       intuicyjne i wymaga pewnego przywyknięcia. Na przykład:

            $ cat f1
            11111
            22222
            33333
            44444
            $ cat f2
            00000
            22222
            33333
            55555
            $ comm f1 f2
                    00000
            11111
                            22222
                            33333
            44444
                    55555

       Pojedyncza  kreska  jako   nazwa   pliku   nakazuje   'comm'   czytanie
       standardowego wejścia zamiast zwykłego pliku.

       Jesteśmy  teraz  gotowi do skonstruowania wymyślnego potoku.  Pierwszym
       zastosowaniem jest licznik częstości słów. Pomaga autorowi  stwierdzić,
       czy nie nadużywa on pewnych słów.

       Pierwszym  krokiem  jest  zmiana  wielkości  wszystkich  liter  z pliku
       wejściowego na jedną wielkość. "to" i "To" przy zliczaniu są tym  samym
       słowem.

            $ tr '[A-Z]' '[a-z]' < whats.gnu | ...

       [tłum.:  zauważ,  że  dla  języka  polskiego,  podobnie jak w następnym
       kroku, należy uwzględnić  dodatkowo  nasze  znaki  diakrytyczne.  Można
       dołączyć  je do podanego zakresu lub, lepiej, posłużyć się klasą znaków
       i ustawieniami narodowymi - zobacz tr(1).]
       Następnym  krokiem  jest  pozbycie  się  znaków  przestankowych.  Słowa
       cytowane  i  niecytowane powinny być traktowane identycznie; najłatwiej
       będzie po prostu wyrzucić zawadzającą interpunkcję.

            $ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_  12]' | ...

       Drugie polecenie 'tr' działa na dopełnieniu podanych znaków, którymi są
       litery,  cyfry,  podkreślenie i odstęp. ' 12' oznacza znak nowej linii,
       należy go  pozostawić.  Dla  dobrego  pomiaru  w  działającym  skrypcie
       powinien być też zawarty znak tabulacji (ASCII tab).

       Na   tym  etapie,  mamy  dane  składające  się  ze  słów  rozdzielonych
       odstępami.  Słowa  zawierają  wyłącznie  znaki  alfanumeryczne  i  znak
       podkreślenia.   Następnym  krokiem  jest rozbicie danych na części tak,
       byśmy mieli po jednym słowie w wierszu. Jak wkrótce zobaczymy, znacznie
       ułatwia to zliczanie.

            $ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_  12]' |
            > tr -s '[ ]' ' 12' | ...

       To  polecenie  zamienia  odstępy w znaki nowej linii. Opcja '-s' ściska
       wielokrotne znaki nowej  linii  wyniku  w  pojedynczy.  Pomaga  nam  to
       uniknąć  pustych  wierszy.  (Znak  '>'  jest tu wtórnym znakiem zachęty
       powłoki.  Powłoka  wypisuje  go,  gdy  zauważy,  że   nie   zakończyłeś
       wpisywania całego polecenia.)

       Teraz  mamy  dane  składające się z jednego słowa w każdym wierszu, bez
       znaków interpunkcyjnych, wszystkie pisane jedną  wielkością.   Jesteśmy
       gotowi do zliczania każdego z nich:

            $ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_  12]' |
            > tr -s '[ ]' ' 12' | sort | uniq -c | ...

       Na tym etapie, dane mogą wyglądać jakoś tak:

              60 a
               2 able
               6 about
               1 above
               2 accomplish
               1 acquire
               1 actually
               2 additional

       Wynik  jest  posortowany  według  słów,  nie  według  liczby wystąpień!
       Chcielibyśmy natomiast mieć jako pierwsze  najczęściej  używane  słowa.
       Na  szczęście,  łatwo  to  osiągnąć  przy  pomocy dwu dodatkowych opcji
       'sort':

       -n     wykonuje sortowanie liczbowe, a nie tekstowe

       -r     odwraca kolejność sortowania

       Ostateczny potok wygląda tak:

            $ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_  12]' |
            > tr -s '[ ]' ' 12' | sort | uniq -c | sort -nr
             156 the
              60 a
              58 to
              51 of
              51 and
             ...

       No, no! Sporo do opowiadania. Nadal jednak obowiązują te  same  zasady.
       Przy pomocy sześciu poleceń, w dwu wierszach (faktycznie jednej długiej
       linii podzielonej dla wygody), stworzyliśmy  program,  który  robi  coś
       ciekawego i pożytecznego, w dużo krótszym czasie niż moglibyśmy napisać
       program w C robiący to samo.

       Niewielkie zmiany w powyższym  potoku  mogą  nam  dać  prosty  korektor
       pisowni!    Do  stwierdzenia,  czy  napisałeś  poprawnie  jakieś  słowo
       wystarczy, że poszukasz go w słowniku. Jeśli w nim  nie  występuje,  to
       możliwe,  że  twoja pisownia jest nieprawidłowa. Tak więc, potrzebujemy
       słownika.  Jeżeli   masz   dystrybucję   Slackware   Linux,   to   plik
       '/usr/lib/ispell/ispell.words'  jest  posortowanym, zawierającym 38.400
       słów, słownikiem.

       Zatem, jak porównać nasz plik ze słownikiem? Jak poprzednio,  utworzymy
       posortowaną listę słów, po jednym w wierszu:

            $ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_  12]' |
            > tr -s '[ ]' ' 12' | sort -u | ...

       Teraz  potrzebujemy  tylko  listy  słów, których NIE MA w słowniku.  Tu
       właśnie pojawia się polecenie 'comm'.

            $ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_  12]' |
            > tr -s '[ ]' ' 12' | sort -u |
            > comm -23 - /usr/lib/ispell/ispell.words

       Opcje '-2' i '-3' likwidują wiersze występujące tylko  słowniku  (drugi
       plik),  i  występujące  w obu plikach. Wiersze obecne tylko w pierwszym
       pliku (standardowe wejście, nasz strumień słów),  są  słowami,  których
       nie  ma  w słowniku. Są to prawdopodobne błędy pisowni.  Taki potok był
       pierwszym etapem budowy korektora pisowni w Uniksie.

       Istnieje jeszcze kilka innych narzędzi wymagających krótkiej  wzmianki.

       grep   szuka w plikach tekstu pasującego do wyrażenia regularnego

       egrep  jak 'grep', ale z bardziej rozbudowanymi wyrażeniami regularnymi

       wc     zlicza wiersze, słowa, znaki

       tee    kopiuje dane do plików i na standardowe wyjście; działa  jak  T-
              kształtka w rurociągu danych

       sed    edytor strumieniowy, zaawansowane narzędzie

       awk    język manipulacji danymi, kolejne zaawansowane narzędzie

       Filozofia  narzędzi programowych daje też następującą radę: "Niech ktoś
       inny zrobi trudną część  pracy".   To  znaczy,  weź  coś,  co  zaspokoi
       większość  twoich potrzeb, a następnie przekształcaj dalej, aż uzyskasz
       pożądaną postać.

       Podsumowując:

       1.     Każdy program  powinien  robić  jedną  rzecz,  ale  dobrze.  Nie
              więcej, nie mniej.

       2.     Łączenie  programów  w  odpowiedni sposób prowadzi do rezultatu,
              gdzie całość jest  większa  od  sumy  części.  Prowadzi  też  do
              nowatorskich  zastosowań  programów,  których  ich autorzy nawet
              sobie nie wyobrażali.

       3.     Programy  nigdy  nie  powinny   wypisywać   dodatkowych   danych
              nagłówkowych  czy  kończących, gdyż mogłyby one zostać przesłane
              potokiem.  (Cecha, o której wcześniej nie wspominaliśmy).

       4.     Niech ktoś inny wykona trudną część roboty.

       5.     Znaj  swoje  narzędzia!  Każdego  programu  używaj  we  właściwy
              sposób.  Jeżeli nie masz odpowiedniego narzędzia - zrób je.

       W  chwili  powstania  tego  artykułu,  wszystkie omawiane programy były
       dostępne    przez    anonimowe    ftp    z     prep.ai.mit.edu     jako
       /pub/gnu/textutils-1.9.tar.gz.    Wersja   1.9  była  wówczas  bieżącą.
       Sprawdź w najbliższym archiwum GNU jaka wersja jest aktualnie  bieżąca.
       Główną siedzibą archiwum jest obecnie ftp.gnu.org.

       Nic  z  tego,  co przedstawiłem w tym artykule nie jest nowe. Filozofia
       Narzędzi Programowych została po raz  pierwszy  wprowadzona  w  książce
       'Software  Tools',  Briana  Kernighana i P.J. Plaugera (Addison-Wesley,
       ISBN 0-201-03669-X).  Książka ta pokazywała jak pisać  i  wykorzystywać
       narzędzia   programowe.    Została   napisana  w  1976,  korzystając  z
       preprocesora FORTRAN-u o nazwie 'ratfor' (RATional FORtran). Wówczas  C
       nie  był  tak  wszechobecny  jak  dziś.  FORTRAN był.  Ostatni rozdział
       przedstawiał 'ratfor' dla procesora FORTRAN-u, napisany w nie  będziesz
       mieć żadnych kłopotów ze zrozumieniem kodu.

       W  1981 książka ta została zaktualizowana i udostępniona jako 'Software
       Tools in Pascal' (Addison-Wesley, ISBN 0-201-10342-7). Obie książki  są
       nadal  drukowane  i  są  rzeczywiście  warte  przeczytania jeśli jesteś
       programistą.   Z  pewnością  bardzo  zmieniły  mój  punkt  widzenia  na
       programowanie.

       Początkowo programy z obu książek były dostępne (na 9-calowej taśmie) z
       Addison-Wesley. Niestety, już tak nie  jest,  mimo  że  możesz  znaleźć
       kopie rozproszone w Internecie. Przez wiele lat działała Software Tools
       Users  Group  -  Grupa  Użytkowników  Narzędzi   Programowych,   której
       członkowie  przenieśli  pierwotne  programy  'ratforu'  na niemal każdy
       system komputerowy z kompilatorem FORTRAN-u. Popularność grupy  zanikła
       w  połowie  lat  80-tych,  gdy  Unix  zaczął  rozpowszechniać  się poza
       uniwersytetami.

       Przy obecnym rozmnożeniu kodu GNU i innych klonów programów uniksowych,
       programom  tym  poświęca się teraz niewiele uwagi. Współczesne wersje C
       są o wiele wydajniejsze  i  robią  więcej  niż  te  programy.  Niemniej
       jednak,   książki   te   są   niezrównane   jako   opis  dobrego  stylu
       programowania, głosząc wciąż cenną filozofię. Gorąco je polecam.

       Podziękowania: chciałbym wyrazić swą wdzięczność Brianowi  Kernighanowi
       z  Bell Labs, pierwszemu Kowalowi Narzędzi Programowych, za przejrzenie
       tego artykułu.

ZOBACZ TAKŻE

       cat(1)      łączenie i wypisywanie plików

       comm(1)     porównywanie dwu posortowanych plików liniami

       csplit(1)   podział pliku na części zależne od kontekstu

       csum(1)     wypisywanie sumy CRC liczby bloków

       cut(1)      wypisywanie wybranych części linii

       expand(1)   zamiana tabulacji na spacje

       fmt(1)      reformatowanie akapitów tekstu

       fold(1)     zawijanie linii wejściowych do zadanej szerokości

       head(1)     wypisywanie początku plików

       join(1)     łączenie linii według wspólnego pola

       md5sum(1)   wypisywanie lub sprawdzanie skrótu danych

       nl(1)       numerowanie linii i wypisywanie plików

       od(1)       wypisywanie plików w formacie ósemkowym i innych

       paste(1)    zlepianie linii plików

       pr(1)       stronicowanie i kolumnowanie plików do wydruku

       ptx(1)      tworzenie indeksu permutacyjnego zawartości pliku

       sort(1)     sortowanie plików tekstowych

       split(1)    podział pliku na części stałej wielkości

       sum(1)      wypisywanie sumy kontrolnej i liczby bloków

       tac(1)      łączenie i wypisywanie odwróconych plików

       tail(1)     wypisywanie końcówki plików

       tr(1)       zamiana, ściskanie, usuwanie znaków

       tsort(1)    sortowanie topologiczne

       unexpand(1) zamiana spacji na tabulacje

       uniq(1)     pozostawianie unikalnych linii w pliku

       wc(1)       wypisywanie liczby bajtów, słów i linii