W systemie Linux, aby wyszukać wszystkie pliki z rozszerzeniem txt, które znajdują się w katalogu /home/user i zaczynają się na literę a lub literę b lub literę c, należy wydać polecenie
A. ls /home/user/abc*.txt
B. ls /home/user/[a-c]*.txt
C. ls /home/user/[!abc]*.txt
D. ls /home/user/a?b?c?.txt
Pytanie z egzaminu CKE, styczeń 2020 (arkusz E.12-SG-20.01).
Polecenie ls /home/user/[a-c]*.txt jest właściwe, bo korzysta z mechanizmu globowania powłoki, czyli dopasowywania wzorców nazw plików jeszcze przed uruchomieniem programu ls. Fragment [a-c] oznacza dokładnie jeden znak z zakresu od a do c, czyli a, b albo c. Potem znak * oznacza dowolny dalszy ciąg znaków, także pusty, a końcówka .txt wymusza rozszerzenie txt. W praktyce wzorzec dopasuje np. /home/user/ala.txt, /home/user/backup.txt i /home/user/cwiczenie.txt, ale nie dopasuje /home/user/dane.txt ani /home/user/Abc.txt, bo w Linuksie wielkość liter zwykle ma znaczenie. Moim zdaniem to jeden z tych drobiazgów w terminalu, które bardzo przyspieszają codzienną pracę administratora. Warto pamiętać, że ls pokazuje pliki w podanym katalogu, ale nie przeszukuje rekurencyjnie podkatalogów. Gdyby chodziło o solidne wyszukiwanie w skryptach albo przeszukiwanie drzewa katalogów, lepszą praktyką byłoby użycie find, np. find /home/user -maxdepth 1 -type f -name '[a-c]*.txt'. Do szybkiego sprawdzenia zawartości katalogu w terminalu podany wariant z ls jest jednak poprawny i czytelny.
W tym zadaniu łatwo pomylić zwykłe znaki w nazwie pliku ze wzorcami powłoki. W Linuksie polecenie ls samo z siebie nie analizuje rozszerzeń w jakiś specjalny sposób, tylko dostaje od powłoki listę nazw, które pasują do podanego wzorca. Dlatego abc*.txt oznacza pliki, których nazwa zaczyna się dosłownie od ciągu abc, na przykład abc.txt albo abc_raport.txt. To nie jest zapis „a lub b lub c”, tylko trzy konkretne litery stojące jedna po drugiej. Taki błąd bierze się często z myślenia, że zapisane obok siebie litery tworzą zbiór możliwości, a w globach tak nie jest. Wzorzec [!abc]*.txt też nie spełnia warunku, bo wykrzyknik wewnątrz nawiasów kwadratowych oznacza negację. Taki zapis dopasuje nazwy zaczynające się od dowolnego znaku innego niż a, b i c, czyli dokładnie odwrotnie niż trzeba. Z kolei a?b?c?.txt jest bardzo konkretnym wzorcem: znak ? zastępuje jeden dowolny znak, więc nazwa musiałaby mieć układ typu aXbYcZ.txt. Nie pasują tu zwykłe pliki zaczynające się na a, b albo c. Poprawnym mechanizmem jest zakres znaków [a-c], bo wskazuje jeden pierwszy znak z dozwolonego przedziału. Z mojego doświadczenia warto odróżniać globy powłoki od wyrażeń regularnych, bo wyglądają podobnie, ale działają trochę inaczej i potrafią narobić zamieszania w skryptach.