TEXTUTILS(1) | Narzędzia tekstowe GNU 2.0 | TEXTUTILS(1) |
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).
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']
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ć.
program_tworzacy_dane | filtr1 | .... | filtrN > koncowe.dane
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:
Następnie, posortować listę:
$ who | cut -c1-8
arnold
miriam
bill
arnold
$ 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:
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.
# cat > /usr/local/bin/listusers
who | cut -c1-8 | sort | uniq
^D
# chmod +x /usr/local/bin/listusers
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.
Interesuje nas kilka opcji:
$ echo ThIs ExAmPlE HaS MIXED case! | tr '[A-Z]' '[a-z]'
this example has mixed case!
- -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:
Pojedyncza kreska jako nazwa pliku nakazuje 'comm' czytanie standardowego wejścia zamiast zwykłego pliku.
$ cat f1
11111
22222
33333
44444
$ cat f2
00000
22222
33333
55555
$ comm f1 f2
00000
11111
22222
33333
44444
55555
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.
[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).]
$ tr '[A-Z]' '[a-z]' < whats.gnu | ...
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ę.
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).
$ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_ 12]' | ...
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.
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.)
$ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_ 12]' |
> tr -s '[ ]' ' 12' | ...
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:
Na tym etapie, dane mogą wyglądać jakoś tak:
$ tr '[A-Z]' '[a-z]' < whats.gnu | tr -cd '[A-Za-z0-9_ 12]' |
> tr -s '[ ]' ' 12' | sort | uniq -c | ...
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':
60 a
2 able
6 about
1 above
2 accomplish
1 acquire
1 actually
2 additional
Ostateczny potok wygląda tak:
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.
$ 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
...
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:
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 | ...
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.
$ 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
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
FSF | sierpień 1999 |