그래서 파일 이름을 입력으로 사용하는 콘솔 플레이어에서 일부 MP3를 재생하고 싶습니다. 내 쉘(zsh)에 의해 확장되는 ls -1 *
위치 에 따라 다음 파일이 있습니다 .*
1 - Main title.mp3
10 - End title.mp3
2 - Intro.mp3
...
그러나 분명히 내가 실제로 주문하는 방식은 다음과 같습니다.
1 - Main title.mp3
2 - Intro.mp3
...
10 - End title.mp3
그렇게 하려면 어떤 쉘 확장 마법이 필요합니까?
나는 영리한 파이프를 사용하여 동일한 결과를 얻을 수 있다는 것을 알고 있지만 sort -h
실제로는 그렇지 않습니다.나는 게으른 타이피스트이기 때문에. 그래서 노래를 추가하기 위해 작은 쉘 스크립트를 작성하지 않는 한, nyxmms2 add /path/to/dir/*.mp3
zsh 확장 내에서 필터링을 수행하는 방법을 찾고 있는 이유는 무엇입니까? 또한 이것이 적용되기 때문에 가능한지 알고 싶습니다. 다른 많은 상황도 마찬가지입니다. 예를 들어 로그 파일이나 개정판 등...
답변1
사용n
글로벌 한정자.
print -lr -- *.mp3(n)
다음을 설정하여 기본 정렬 순서를 변경할 수 있습니다.numeric_glob_sort
옵션.
setopt numeric_glob_sort
print -lr -- *.mp3
numeric_glob_sort
한 패턴이 적용될 수 있는 동안 사전식 순서가 필요한 경우 n
glob 한정자를 무효화하세요.
print -lr -- *(^n)
답변2
ls
한 가지 접근 방식은 명령을 통해 출력을 실행하여 sort
출력 표시 방법을 제어하는 것입니다.
사람이 읽을 수 있는 형식으로 항목을 정렬하는 -h
(aka. ) 를 사용할 수 있습니다 .--human-numeric-sort
$ ls | sort -h
1 - Main title.mp3
2 - Main title.mp3
10 - Main title.mp3
편집 #1 - OP의 의견 다루기
위의 내용은 다음과 같이 별칭으로 래핑될 수 있습니다.
$ alias lss="ls | sort -h"
위 명령을 실행하면 다음과 같이 줄어듭니다.
$ lss
1 - Main title.mp3
2 - Main title.mp3
10 - Main title.mp3
참고자료
답변3
zsh
globbing 에서 정렬 순서를 변경할 수 있습니다 (참조:질의 답변), 그러나 ls
인수는 기본적으로 사전순으로 정렬됩니다.
ls
GNU인 경우 옵션을 사용하여 숫자로 정렬 ls
할 수 있습니다 .-v
ls -1v
또는:
ls -1vd -- *
는 의 출력 , 즉 가 보다 큰 것을 정렬하는 반면 및 의 글로빙 한정자는 버전 번호(예를 들어 1.20이 1.4보다 큼)와 같은 항목을 정렬하는 데 적합 하기 sort -h
때문에 와 동일하지 않습니다 .sort -h
du -h
1.12G
999M
ls -v
zsh
(n)
이러한 사항을 이해하는 글로빙을 원한다면 이를 위한 zsh 정렬 기능을 작성해야 합니다.
zsh를 사용하면 함수로 glob 정렬 순서를 정의하고 *(o+that-function)
. 변수 that-function
에서 정렬하기 위해 파일 이름을 취하고 $REPLY
동일한 변수로 반환해야 합니다. 그런 다음 사전식으로(또는 제공된 zsh
경우 숫자로) 정렬할 수 있습니다 .n
다음과 같은 것 :
h() {
local -A x
local match
setopt localoptions extendedglob
x=(k 1 K 1 M 2 G 3 T 4 P 5 E 6)
REPLY=${REPLY//(#b)((|[0-9]#.)[0-9]##)([${(kj::)x}])/$((match[1]*2**$x[$match[3]]0))}
}
1.1G를 모두 해당 값(1181116006.4)으로 대체합니다.
그런 다음 다음과 같이 사용할 수 있습니다.
ls -1Ud -- *(no+h)
( -U
GNU ls
옵션은 다음과 같습니다.ls
~ 아니다인수를 정렬합니다).
그러나 소수 부분이 있는 숫자의 경우에는 잘 작동하지 않습니다. 예를 들어 1.20
다음과 같이 정렬됩니다.1.3
$ ls
1.20 1.3 3.1G 500M
$ ls -v1Ud -- *(no+h)
1.3
1.20
500M
3.1G
선택적 접미사(예: -1e20M, 1E-20, 100k, 3000M)를 사용하여 모든 종류의 소수 부동 숫자를 정렬하는 경우 zsh
사전식 또는 숫자적으로 양의 십진 정수로만 정렬할 수 있으므로 이를 변환하는 함수가 필요합니다. 동일한 순서로 사전순으로 정렬되는 문자열 또는 동일한 순서로 숫자로 정렬되는 양의 십진 정수로 변환됩니다.
zsh
가능한 경우 64비트 숫자로 부동 소수점 및 소수점 연산을 수행하므로 해당 숫자(또는 적어도 zsh
부동 소수점이 지원하는 범위)를 0에서 2 63 사이의 정수로 바꾸는 부동 소수점 함수를 적용할 수 있습니다 . 로그 함수를 사용하는 것이 옵션이 될 수 있습니다. 다음과 같은 것 :
zmodload zsh/mathfunc
h() {
local -A x
local match v
setopt localoptions extendedglob
x=(k 1 K 1 M 2 G 3 T 4 P 5 E 6 Z 7 Y 8)
REPLY=${REPLY//(#b)([-+]|)(([0-9]#.|)[0-9]##([eE]([-+]|)[0-9]##|))\
([${(kj::)x}]|)/[$(([#10]1e15*(1500+ $match[1](745+log((v=$match[2]\
${${match[2]##*[Ee.]*}:+.}*2.**$x[$match[6]]0)==0?2.48e-324:v)))))]}
}
다음과 같이 사용됩니다.
print -rl -- *(no+h)
또는 예를 들어 100000000000000001과 100000000000000002를 구별하기 위해 숫자 정렬로 돌아가려면(부동 소수점 정밀도와 동일한 로그를 가짐 zsh
):
print -rl -- *(noe:h:on)
그러면 다음보다 훨씬 더 나은 결과를 얻을 수 있습니다 sort -h
.
$ ls | sort -h
-4
-3
+20
a2
b1
b10
b2
1e-20Y
1e3
1.20
1.3
3
20
999
1000 1e9
1000 900M
1001
1024
1k
12k
0.000000001G
$ print -rl -- *(noe:h:on)
-4
-3
0.000000001G
1.20
1.3
3
20
+20
999
1e3
1000 900M
1000 1e9
1001
1k
1024
1e-20Y
12k
a2
b1
b2
b10
이제 특정 nyxmms2 문제에 대해 Gilles의 답변을 보완하기 위해 나는 게으른 타이피스트입니다. 이번에는선택("주문" 대신) 다음과 같은 음악 파일 기능을 사용하세요.
m() [[ $REPLY == (#i)*.(mp3|ogg)(-.) ]]
nyxmms2 *Zep*(n+m)
또는 변수를 사용하십시오.
m='.(#i)(mp3|ogg)(n-.)'
nyxmms2 *Zep*$~m
또는 전역 별칭:
alias -g @m='./*.(#i)(mp3|ogg)(n-.)'
nyxmms2 @m
숫자글로브 정렬을 켜려면 nyxmms2
다음을 수행할 수 있습니다.
preexec() {[[ $1 = nyxmms2* ]] && setopt numericglobsort}
precmd setopt nonumericglobsort
답변4
이를 위해 언제든지 쉘 확장을 사용할 수 있습니다.
nyxmms2 add $(ls /path/to/dir/*.mp3 | sort -n)
음악을 다루고 있으므로 "재생 목록"을 만들 수도 있습니다.
ls /path/to/album/or/song/*.mp3 | sort -n >> /path/to/playlist
nyxmms2 add < /path/to/playlist