Mam katalog wypełniony plikami o nazwach takich jak logXX
gdzie XX to dwuznakowa, zerowa, duża liczba szesnastkowa, na przykład:
log00
log01
log02
...
log0A
log0B
log0C
...
log4E
log4F
log50
...
Ogólnie będzie mniej niż powiedzmy 20 lub 30 plików ogółem. Data i godzina w moim konkretnym systemie nie są czymś, na czym można polegać (system osadzony bez wiarygodnych źródeł czasu NTP lub GPS). Jednak nazwy plików będą niezawodnie zwiększać, jak pokazano powyżej.
Chciałbym grep
przejrzeć wszystkie pliki dla jednego najnowszego wpisu dziennika określonego typu, miałem nadzieję cat
na pliki razem, takie jak ...
cat /tmp/logs/log* | grep 'WARNING 07 -' | tail -n1
Jednak dotarło do mnie, że różne wersje bash
lub sh
lub zsh
itd. Mogą mieć różne wyobrażenia o tym, jak *
jest rozwinięty.
man bash
Strona nie powiedzieć, czy ekspansja *
byłaby zdecydowanie rosnąco alfabetyczna lista pasujących nazw. Wygląda na to, że rośnie w górę za każdym razem, gdy wypróbowałem go na wszystkich dostępnych mi systemach - ale czy jest to ZDEFINIOWANE zachowanie, czy tylko specyficzne dla implementacji?
Innymi słowy, czy mogę całkowicie polegać na cat /tmp/logs/log*
konkatenacji wszystkich moich plików dziennika w kolejności alfabetycznej?
sort
jest taka sama jak w przypadku powłoki, gdy rozwija ona wzorzec globowania nazw plików.cat
pomocą,grep -h pattern /tmp/logs/log*
aby ukryć poprzedzające nazwy plików do dopasowań. (Przynajmniej z GNU grep, nie sprawdziłem POSIX-a lub busyboksa.)cat
, jest to bezużyteczne użyciesort
Odpowiedzi:
We wszystkich powłokach globusy są domyślnie sortowane. Byli już przy pomocy
/etc/glob
pomocnika zwanego przez powłokę Kena Thompsona, aby rozwinąć globusy w pierwszej wersji Uniksa na początku lat 70. (i które dały globusom swoją nazwę).Ponieważ
sh
POSIX wymaga sortowania według sposobustrcoll()
, tzn. Przy użyciu kolejności sortowania w ustawieniach regionalnych użytkownika, tak jakls
choć niektórzy nadal to robiąstrcmp()
, opartej tylko na wartościach bajtów.Możesz zauważyć powyżej, że w przypadku powłok wykonujących sortowanie na podstawie ustawień regionalnych, tutaj w systemie GNU z
en_GB.UTF-8
ustawieniami narodowymi,-
nazwy plików są ignorowane podczas sortowania (większość znaków interpunkcyjnych). Jestó
on sortowany w bardziej oczekiwany sposób (przynajmniej dla Brytyjczyków), a wielkość liter jest ignorowana (z wyjątkiem przypadków decydujących o powiązaniach).Jednak zauważysz pewne niespójności dla log for log②. Jest tak, ponieważ kolejność sortowania ① i ② nie jest zdefiniowana w ustawieniach narodowych GNU (obecnie; mam nadzieję, że zostanie to kiedyś naprawione). Sortują to samo, więc otrzymujesz losowe wyniki.
Zmiana ustawień regionalnych wpłynie na kolejność sortowania. Możesz ustawić ustawienia regionalne na C, aby uzyskać
strcmp()
sortowanie podobne do:Zauważ, że niektóre ustawienia narodowe mogą powodować pewne nieporozumienia, nawet w przypadku ciągów znaków all-ASCII all-alnum. Jak te czeskich (w systemach GNU przynajmniej) gdzie
ch
jest to elementem porównawczym , który sortuje poh
:Lub, jak wskazał @ninjalj, jeszcze dziwniejsze w węgierskich lokalizacjach:
W
zsh
możesz wybrać sortowanie za pomocą kwalifikatorów glob . Na przykład:Numeryczne sortowanie
echo *(n)
można również włączyć globalnie za pomocąnumericglobsort
opcji:Jeśli jesteś (tak jak ja) zdezorientowany tym zamówieniem w tym konkretnym przypadku (tutaj, używając mojej brytyjskiej lokalizacji), zobacz tutaj, aby uzyskać szczegółowe informacje.
źródło
&C<cs<<<Cs<<<CS
, natomiast&C<cs<<<cS<<<Cs<<<CS
jest oznaczony jako proponowany projekt eksperymentalny. Sądząc z niektórych starszych danych zaimportowanych do CLDR, starsze systemy AIX i MS wydawały się preferować widok „małe litery, a potem wielkie litery to 2 różne elementy sortowania”.Strona podręcznika bash określa:
źródło
man
renderowaniu szpachli lub tekstu ... jeśli szukany tekst zostanie „zawinięty”, wówczas polecenie / search go nie znajdzie. Właśnie zmaksymalizowałem mój terminal ibash
. Tho OP był również zainteresowany „zsh itp.”O ile nie uruchomisz niektórych bardzo konkretnych opcji powłoki w niektórych powłokach, wynik będzie na pewno taki sam.
Kolejność jest określona w standardzie POSIX :
Zobacz także LC_COLLATE Kategoria w Locale POSIX , która w skrócie mówi, że jeśli
LC_COLLATE=C
, to rzeczy są uporządkowane w kolejności ASCII.bash
Instrukcja wspominaksh93
izsh
ma podobne sformułowanie, co prowadzi mnie do przekonania, że pod tym względem są zgodne ze standardem POSIX.Inne powłoki, takie jak
pdksh
idash
nie mówią nic o sortowaniu nazw plików wynikających z globowania nazw plików. Kusi mnie, aby wierzyć, że oznacza to, że nadal przestrzegają tego samego standardu, przynajmniej podczas korzystania z ustawień regionalnych POSIX. Z mojego doświadczenia nie spotkałem powłoki, która jawnie „dziwnie” sortuje nazwy plików ASCII.źródło
numericglobsort
opcjęzsh
, która wpłynie na sortowanie. Chociaż wolę włączyć tę opcję dla poszczególnych globów,echo *(n)
niż włączać tę opcję globalnie.--posix
opcją wiersza poleceń lub wykonaćset -o posix
posix
tryb Basha nie wpływa na sortowanie rozszerzenia znaków globowania nazw plików . Zobacz gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html To prowadzi mnie do przekonania (raczej raczej), że sortowanie jest zgodne z POSIX.Jeśli głównym celem jest sortowanie plików wejściowych według wieku, najpierw najstarsze, możesz napisać
A jeśli w grę wchodzą również dzienniki obrócone i skompresowane:
źródło