Provided by:
manpages-pl_20060617-1_all 
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