로케일에 따라 ls 출력을 정렬하지만 영숫자가 아닌 문자는 무시하지 않습니다.

로케일에 따라 ls 출력을 정렬하지만 영숫자가 아닌 문자는 무시하지 않습니다.

_b, a, c, 파일을 포함하는 디렉토리가 있다고 가정 č합니다 d. cs_CZ.UTF8 로케일을 기준으로 파일을 정렬하고 싶지만아니요밑줄을 무시하십시오. 즉, 다음과 같습니다: _b a c č d.

현재 파일은 다음과 같이 정렬되어 있습니다: ls. 내가 찾은 모든 답변은 을 사용하는 것이 좋지만 순서는 다음과 같이 변경됩니다. ( 이제는 과 사이가 아니라 끝에 있습니다 . )ls | sorta _b c č dLC_COLLATE=C_b a c d ččcd

이것을 달성할 수 있는 방법이 있나요?

a-n.pdf a-p.pdf a.pdf c č d밑줄 이외의 문자에도 관심이 있습니다. 즉, 대신 이것을 기준으로 정렬하고 싶습니다 a-n.pdf a.pdf a-p.pdf c č d. (편집: 실제로 a.pdf a-n.pdf a-p.pdf c č d영숫자가 아닌 문자가 무시되지 않는 한 그것도 괜찮습니다.)

다음은 내가 원하는 답변이 아닙니다.

  • LC_COLLATE=C위와 같이 사용되며,
  • 예를 들어, ls _*; ls [^_]*질문은 밑줄에 관한 것이 아니기 때문에 쉘 확장을 사용하십시오.

답변1

GNU 시스템에서는 알파가 아닌 항목에 NUL을 추가하는 것이 도움이 될 수 있습니다.

$ ls | sed 's/[^[:alpha:]]/&\x0/g' | sort | tr -d '\0'
_b
a
c
č
d

파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다. 일반적으로 sort파일 이름 자체는 여러 줄로 구성될 수 있으므로 파일 이름 목록을 정렬할 수 없습니다 .

정렬하기 전에 여기에서 파일 이름의 줄 바꿈을 바꿀 수 있습니다 /. 그리고 zsh:

print -rNC1 -- *(N) | # print NUL-delimited
  tr '\n\0' '/\n' |
  sed 's/[^[:alpha:]]/&\x0/g' |
  sort |
  tr -d '\0' |
  tr '/' '\n'

또는 사후 처리가 가능하도록 목록을 NUL로 구분하여 유지하세요.

print -rNC1 -- *(N) | # print NUL-delimited
  tr '\n\0' '/\n' |
  sed 's/[^[:alpha:]]/&\x0/g' |
  sort |
  tr -d '\0' |
  tr '/\n' '\n\0'

strcoll()정렬을 위한 API는 두 개의 NUL 종료 문자열을 사용합니다. 레거시 sort구현은 텍스트 입력만 지원하고 텍스트 입력은 NUL을 제외하므로 괜찮습니다. 그러나 sort표준 텍스트 유틸리티의 대부분의 GNU 구현과 마찬가지로 GNU는 NUL 및 해당 입력을 지원합니다.

GNU가 NUL이 있는 줄을 어떻게 처리하는지 정확히 모르지만 sort내 생각에는 NUL의 줄을 나누고 세그먼트를 일대일로 비교하는 것 같습니다. 예를 들어 foo_\0car비교할 때는 먼저 비교한 다음 비교하세요.foobar_\0morefoo_foobar_

zshoerder ( 일부 코드 평가 o기반 e) 또는 o+functionglob 한정자를 사용한 변환을 사용하여 glob의 순서를 정의할 수도 있습니다 . 하지만 전화하기 전에 strcoll(),zshNUL 제거sort이므로 위의 GNU와 동일한 변환을 사용할 수 없습니다 .

대신, 0알파 시퀀스가 ​​아닌 시퀀스 앞에 s를 추가하고 1알파 시퀀스 앞에 s를 추가할 수 있습니다.

존재하다~/.zshrc

set -o extendedglob
mysort() {
  REPLY=${REPLY//(#m)[^[:alpha:]]##/0$MATCH}
  REPLY=${REPLY//(#m)[[:alpha:]]##/1$MATCH}
}

그 다음에:

$ print -rC1 -- *(No+mysort)
_b
a
c
č
d

관련 정보