와 함께글로벌 예선zsh
파일 이름 와일드카드 패턴 일치 결과는 여러 가지 방법으로 정렬 될 수 있습니다 . 예를 들어, 이 패턴은 *(om)
수정 타임스탬프를 기준으로 현재 디렉터리에서 숨겨지지 않은 모든 이름과 일치합니다.
하지만 가끔은 방법이 있었으면 좋겠어무작위화정렬(예: 파일의 무작위 샘플 가져오기) 내가 아는 한, 이 작업을 직접적으로 수행하는 한정자는 없습니다.
zsh
질문: 파일 이름 글로빙 패턴에서 임의의 경로 이름 목록을 얻는 방법은 무엇입니까 ?
답변1
임의 정렬 키(글로벌 예선 oe
)::
*(Noe\''REPLY=$RANDOM,$RANDOM'\')
설명하다:
oe
그 뒤에는 단일 문자 구분 기호, 코드 및 다른 구분 기호가 옵니다. 코드 블록에는 구분 기호가 포함될 수 없습니다. 전역 한정자 자체를 구문 분석할 때 특수 문자가 구문 분석되지 않도록 특수 문자를 이스케이프해야 합니다.- 나는
'
구분 기호로 사용하고(이스케이프가 필요하므로 백슬래시 사용)'
존재할 수 있는 특수 문자를 보호하기 위해 코드를 래핑합니다. 이렇게 하면'
. - 일치하는 각 파일 이름에 대해 코드 블록이 차례로 실행됩니다.
REPLY
처음에는 파일 이름으로 설정되고 코드에 의해 설정된 모든 것이REPLY
정렬 키로 사용됩니다.
$n
요소를 무작위로 샘플링하려면 […]
한정자를 추가하세요.
*(Noe\''REPLY=$RANDOM,$RANDOM'\'[1,$n])
때로는 일부 요소가 동일한 정렬 키를 가지므로 모든 순열의 가능성이 동일하지 않으며 정렬 기능을 디렉터리 순서로 목록에 적용한 결과를 보존하는 쪽으로 약간의 편향이 있지만 편향은 작습니다. 나는 이것을 $RANDOM,$RANDOM
정렬 키로 사용하고 있지만 $RANDOM
편향을 줄이기 위한 것은 아닙니다. $RANDOM
15자리 숫자이고 파일 수가 2^15에 가까워질수록 편향이 눈에 띄게 됩니다.
$RANDOM
약간의 편향이 문제가 되지 않는 경우 샘플링에 충분합니다 . 보안과 관련된 어떤 것에도 적합하지 않습니다. 안전한 무작위 순열을 원하면 GNU coreutils를 사용하세요.shuf
. (좋아하는 운영 체제에 기본 기능이 부족 shuf
하고 어떤 이유로 GNU coreutils를 설치하고 싶지 않은 경우 다음을 시도해 볼 수 있습니다.이하라의 재깨달음대신에. )
securely_permuted=("${(0)$(printf '%s\0' *(N) | shuf -z))}")
또는 더 간단한 버전은 명령줄 길이 제한에 도달할 수 있습니다.
securely_permuted=("${(0)$(shuf -z -- *(N)))}")
1 실험적으로 순서는 안정적이지만(예: *(omoe\''REPLY=1'\')
동일 *(om)
) 순서가 *(oe\''REPLY=1'\')
일치하지 않습니다 *(oN)
. 그럼에도 불구하고 이는 일부 특정 순서에 유리한 작은 편차입니다.