logXX
XX는 다음 과 같은 이름을 가진 파일로 채워진 디렉토리가 있습니다 .
log00
log01
log02
...
log0A
log0B
log0C
...
log4E
log4F
log50
...
일반적으로 총 파일 수가 20 개 또는 30 개 미만입니다. 내 특정 시스템의 날짜 및 시간은 신뢰할 수있는 NTP 또는 GPS 시간 원본이없는 내장형 시스템이 아닙니다. 그러나 파일 이름은 위에 표시된대로 안정적으로 증가합니다.
grep
특정 유형의 가장 최근의 단일 로그 항목에 대한 모든 파일 을 살펴 보고 싶습니다 cat
.
cat /tmp/logs/log* | grep 'WARNING 07 -' | tail -n1
그러나 나에게의 다른 버전이 발생 bash
하거나 sh
또는 zsh
이 방법에 대한 다른 아이디어를 가질 수 등을 *
확장됩니다.
이 man bash
페이지는 확장이 *
확실히 일치하는 파일 이름의 알파벳순 목록 인지 여부를 말하지 않습니다 . 내가 사용할 수있는 모든 시스템에서 시도 할 때마다 오름차순 인 것처럼 보이지만 정의 된 동작입니까? 구체적입니까?
즉, cat /tmp/logs/log*
모든 로그 파일을 알파벳 순서로 연결 하는 데 절대적으로 의존 할 수 있습니까?
답변
모든 쉘에서 글롭은 기본적으로 정렬됩니다. 그들은 이미/etc/glob
70 년대 초 유닉스의 첫 번째 버전에서 글로브를 확장하기 위해 Ken Thompson의 쉘에 의해 호출 된 도우미에 의해있었습니다 (그리고 글로브에 이름을 지어주었습니다).
의 경우 sh
POSIX는을 기준으로 정렬해야합니다 strcoll()
. 즉 ls
일부 사용자는 로케일을 통해 정렬하는 것처럼 사용자의 로케일에서 정렬 순서를 사용합니다 strcmp()
.
$ dash -c 'echo *'
Log01B log-0D log00 log01 log02 log0A log0B log0C log4E log4F log50 log① log② lóg01
$ bash -c 'echo *'
log① log② log00 log01 lóg01 Log01B log02 log0A log0B log0C log-0D log4E log4F log50
$ zsh -c 'echo *'
log① log② log00 log01 lóg01 Log01B log02 log0A log0B log0C log-0D log4E log4F log50
$ ls
log② log① log00 log01 lóg01 Log01B log02 log0A log0B log0C log-0D log4E log4F log50
$ ls | sort
log②
log①
log00
log01
lóg01
Log01B
log02
log0A
log0B
log0C
log-0D
log4E
log4F
log50
로케일을 기반으로 정렬하는 쉘 (여기서 로케일이있는 GNU 시스템의 en_GB.UTF-8
경우) -
에서 파일 이름의 정렬은 무시됩니다 (대부분의 문장 부호 문자). 이 ó
방식은보다 예상 된 방식으로 정렬되며 (적어도 영국인에게는 해당) 대소 문자는 무시됩니다 (관계 결정시 제외).
그러나 log① log②에는 약간의 불일치가 있습니다. 이것은 ①과 ②의 정렬 순서가 GNU 로켈에서 정의되어 있지 않기 때문입니다 (현재는 희망적으로 언젠가는 고쳐질 것입니다). 그들은 동일하게 정렬되므로 임의의 결과를 얻습니다.
로캘을 변경하면 정렬 순서에 영향을줍니다. 로케일을 C로 설정하여 strcmp()
비슷한 정렬 을 얻을 수 있습니다 .
$ bash -c 'echo *'
log① log② log00 log01 lóg01 Log01B log02 log0.2 log0A log0B log0C log-0D log4E log4F log50
$ bash -c 'LC_ALL=C; echo *'
Log01B log-0D log0.2 log00 log01 log02 log0A log0B log0C log4E log4F log50 log① log② lóg01
모든 로케일은 모든 ASCII 문자열에 대해서도 일부 로케일이 혼동을 일으킬 수 있습니다. 체코 어와 마찬가지로 (적어도 GNU 시스템에서는) 다음 ch
과 같은 정렬 요소 가 있습니다 h
.
$ LC_ALL=cs_CZ.UTF-8 bash -c 'echo *'
log0Ah log0Bh log0Dh log0Ch
또는 @ninjalj가 지적한 것처럼 헝가리어 로켈에서 더 이상한 것들도 있습니다.
$ LC_ALL=hu_HU.UTF-8 bash -c 'echo *'
logX LOGx LOGX logZ LOGz LOGZ logY LOGY LOGy
에서 zsh
, glob 한정자를 사용 하여 정렬을 선택할 수 있습니다 . 예를 들어 :
echo *(om) # to sort by modification time
echo *(oL) # to sort by size
echo *(On) # for a *reverse* sort by name
echo *(o+myfunction) # sort using a user-defined function
echo *(N) # to NOT sort
echo *(n) # sort by name, but numerically, and so on.
다음 옵션을 echo *(n)
사용하여 숫자 정렬을 전체적으로 활성화 할 수도 있습니다 numericglobsort
.
$ zsh -c 'echo *'
log① log② log00 log01 lóg01 Log01B log02 log0.2 log0A log0B log0C log-0D log4E log4F log50
$ zsh -o numericglobsort -c 'echo *'
log① log② log00 lóg01 Log01B log0.2 log0A log0B log0C log01 log02 log-0D log4E log4F log50
당신이 (나와 같이) 특정 인스턴스 (여기서 영국 로케일을 사용하는)의 순서로 혼란 스러우면 여기 를 참조하십시오.
답변
bash의 맨 페이지는 다음을 지정합니다.
경로명 확장
하지 않는 단어 분할 후
-f
옵션이 설정되어, 배쉬는 문자에 대한 각 단어를 검색*
,?
및[
. 이러한 문자 중 하나가 나타나면 단어는 패턴으로 간주되고 패턴 […]과 일치하는 알파벳순으로 정렬 된 파일 이름 목록으로 대체됩니다.
답변
일부 쉘에서 매우 특정한 쉘 옵션을 트리거하지 않으면 출력이 동일하게 보장됩니다.
패턴이 기존 파일 이름 또는 경로 이름과 일치하면 패턴이 해당 로케일 및 경로 이름으로 바뀌고 현재 로케일에서 유효한 조합 순서에 따라 정렬됩니다 . 이 조합 순서가 모든 문자의 총 순서를 갖지 않으면 (XBD LC_COLLATE 참조) 동일하게 조합 된 파일 이름 또는 경로 이름은 POSIX 로케일의 조합 순서를 사용하여 바이트 단위로 더 비교되어야합니다.
POSIX 로케일의 LC_COLLATE 카테고리를 참조하십시오. 간단히 말하면 LC_COLLATE=C
ASCII 순서로 정렬됩니다.
bash
매뉴얼은 언급
LC_COLLATE
이 변수는 경로 이름 확장 결과를 정렬 할 때 사용되는 데이터 정렬 순서를 결정하고 경로 이름 확장 및 패턴 일치 내의 범위 표현식, 동등성 클래스 및 배열 시퀀스의 동작을 결정합니다.
ksh93
그리고 zsh
그들은이 점에서 POSIX 표준에 따라 믿고 날 리드 유사한 표현을 가지고 있습니다.
다른 쉘은, 같은 pdksh
및 dash
파일 이름 대체 (globbing)에서 발생하는 파일 이름의 정렬에 대해 아무 말도하지 않습니다. 최소한 POSIX 로캘을 사용할 때 동일한 표준을 준수한다는 의미입니다. 내 경험상 ASCII 파일 이름을 “이상하게”정렬하는 쉘을 발견하지 못했습니다.
답변
주요 목표가 입력 파일을 나이별로 정렬하는 것입니다 (가장 오래된 것부터).
(cd /tmp/logs; cat `ls -rt log*`) | grep whatever
그리고 회전 및 압축 로그도 관련이있는 경우 :
(cd /tmp/logs; zcat -f `ls -rt log*`) | grep whatever