300 개의 데이터 파일을 보유한 디렉토리가 있다고 가정하십시오. 해당 파일 중 200 개를 임의로 선택하여 다른 디렉토리로 옮기고 싶습니다. 유닉스 / 리눅스에서 그렇게 할 수있는 방법이 있습니까?
shuf
하고 head
(또는 그냥 사용 shuf -n
, 맨 페이지를 읽어야합니다 ...)
300 개의 데이터 파일을 보유한 디렉토리가 있다고 가정하십시오. 해당 파일 중 200 개를 임의로 선택하여 다른 디렉토리로 옮기고 싶습니다. 유닉스 / 리눅스에서 그렇게 할 수있는 방법이 있습니까?
shuf
하고 head
(또는 그냥 사용 shuf -n
, 맨 페이지를 읽어야합니다 ...)
답변:
시스템에가 shuf
있는 경우이를 매우 편리하게 사용할 수 있습니다 (추악한 파일 이름 처리).
shuf -zen200 source/* | xargs -0 mv -t dest
당신이하지 않으면 shuf
하지만이 sort
걸리는 것을 -R
,이 작업을해야합니다 :
find source -type f -print0 | sort -Rz | cut -d $'\0' -f-200 | xargs -0 mv -t dest
shuf
호출되지 않습니다 tros
.)
모든 파일 이름을 bash의 "files"라는 배열에 넣습니다.
files=( * )
배열의 크기 :
echo ${#files[@]}
샘플 크기로 2/3를 정의하십시오.
take=$((2*${#files[@]}/3))
for i in $(seq 1 $take)
do
r=$((RANDOM%${#files[@]}))
echo ${files[r]}
done
이것은 중복 선택되며, 되어 있지 공백 등으로 파일 이름 테스트.
중복을 피하는 가장 간단한 방법은 모든 파일을 반복하고 2/3 확률로 각 파일을 선택하는 것이지만 반드시 200 개의 파일로 이어질 수는 없습니다.
목록에서 파일을 선택하면 요구 사항이 충족됩니다.
#!/bin/bash
files=( * )
# define 2/3 of them as sample size:
take=$((2*${#files[@]}/3))
while (( i < $take ))
do
r=$((RANDOM%${#files[@]}))
f=${files[r]}
if [[ -n $f ]]
then
i=$((i+1))
echo ${files[r]}
unset files[r]
fi
done
$RANDOM
0에서 32767 사이의 값만 가질 수 있으므로 32768 개가 넘는 파일이 있으면 제대로 작동하지 않습니다. 또한 페치는 첫 번째 파일을 향해 바이어스됩니다.
통계적으로 임의적이어야하는 경우을 사용하지 않아야합니다 RANDOM % ${#keys[@]}
. 치다:
$RANDOM
32768 개의 고유 한 값이 있습니다따라서 첫 번째 항목을 선택할 때 68 개의 첫 번째 요소 각각에 대해 110 / 32768 ~ = 0.33569 %의 확률이 있고 다른 232 개의 요소 각각에 대해 109 / 32768 ~ = 0.33264 %의 확률이 있습니다. 피킹은 다른 확률로 여러 번 반복되지만 32768 % ${#keys[@]} -ne 0
, 항상 첫 번째 요소를 향해 바이어스 되므로 오류가 발생합니다.
이것은 편향되지 않아야하며 모든 파일 이름으로 작동합니다.
while IFS= read -r -d '' -u 9
do
mv -- "$REPLY" /target/dir
done 9< <(find /source/dir -mindepth 1 -print0 | shuf -n 200 -z)
list.files()
.