사람이 읽을 수 있는 형식의 숫자로 확장

사람이 읽을 수 있는 형식의 숫자로 확장

그래서 파일 이름을 입력으로 사용하는 콘솔 플레이어에서 일부 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유효할 수 있는 패턴의 사전순 정렬이 필요한 경우 nglob 한정자를 취소하세요.

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(참조:자일스의 대답), 그러나 ls해당 인수는 어쨌든 정렬되며 기본적으로 사전순으로 정렬됩니다.

lsGNU 라면 ls-v옵션을 사용하여 숫자로 정렬할 수 있습니다.

ls -1v

또는:

ls -1vd -- *

is는 1.20 이 1.4보다 큰 출력 과 같은 항목을 정렬하는 반면 및 의 와일드카드 한정자 는 버전 번호(예: 1.20이 1.4보다 큰 항목)를 정렬하기 sort -h때문에 동일하지 않습니다 .sort -hdu -h1.12G999Mls -vzsh(n)

이를 이해하는 globbing을 정말로 원한다면 이를 위한 zsh 정렬 함수를 작성해야 합니다.

zsh를 사용 하면 함수 를 사용하여 전역 정렬 순서 를 정의 하고 이를 *(o+that-function).that-function$REPLYzshn

그것은 다음과 같습니다:

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)

( -UGNU 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비트 숫자를 사용하여 수행되므로 부동 소수점 함수를 적용하여 이러한 숫자(또는 적어도 부동 소수점 숫자가 지원하는 범위)를 0에서 263zsh 까지의 정수 로 변환할 수 있습니다. 로그 함수를 사용하는 것이 옵션일 수 있습니다. 그것은 다음과 같습니다:

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 질문에 대해 Giles의 답변을 보완하기 위해 나는 당신은 게으른 타이피스트입니다. 이번에는 정의할 수도 있습니다선택하다("정렬" 대신) 다음과 같은 음악 파일 기능:

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

관련 정보