한 폴더에 있는 350개 정도의 파일 이름을 무작위로 추출하고 싶지만 파일의 원래 이름은 모두 갖고 싶습니다. 즉, 폴더의 모든 이름이 원래 이름에서 무작위로 생성되고 새 이름이나 누락된 이름이 없기를 원합니다. 가능합니까?
(내 질문을 명확하게 설명하지 않은 경우 이 질문을 자유롭게 편집하십시오.)
답변1
mkdir aux
ls | shuf > a # a=randomize list of files
(tail -n +2 a ; head -1 a) > b # b=rotate a one line
paste a b > c # c=(name1 name2)*
gawk '{system( "mv " $1 " aux/" $2)}' c # mv name1 -> aux/name2
mv aux/* . # mv aux/name -> name
rm a b
c
필요한 경우 복구를 계속하십시오 . (보조 파일에 더 나은 이름을 선택하십시오)
답변2
└-(>:) for i in `seq -w 1 10`; do echo $i > nonce-$i; done
└-(>:) ls
nonce-01 nonce-02 nonce-03 nonce-04 nonce-05 nonce-06 nonce-07 nonce-08 nonce-09 nonce-10
└-(>:) for i in nonce*; do echo $i; cat $i; done
nonce-01
01
nonce-02
02
nonce-03
03
nonce-04
04
nonce-05
05
nonce-06
06
nonce-07
07
nonce-08
08
nonce-09
09
nonce-10
10
└-(>:) ../shuffle test
└-(>:) for i in nonce*; do echo $i; cat $i; done
nonce-01
06
nonce-02
03
nonce-03
04
nonce-04
02
nonce-05
09
nonce-06
10
nonce-07
05
nonce-08
08
nonce-09
07
nonce-10
01
코드는 다음과 같습니다.
#!/bin/bash
[ -z $1 ] && echo 'please submit a target directory' && exit 1
TargetDir=${1}
cd $TargetDir
Sourcearray=( * )
function checkArray
{
for item in ${dest[@]}
do
[[ "$item" == "$1" ]] && return 0 # Exists in dest
done
return 1 # Not found
}
#let's shuffle the array randomly
while [ "${#dest[@]}" -ne "${#Sourcearray[@]}" ]
do
rand=$[ $RANDOM % ${#Sourcearray[@]} ]
checkArray "${Sourcearray[$rand]}" || dest=(${dest[@]} "${Sourcearray[$rand]}")
done
let i=0
#let mv the source file to dest file name
while [[ "${i}" -ne "${#dest[@]}" ]] ; do
mv ${Sourcearray[$i]} tmp-${dest[$i]}
let i=$i+1
done
# and rename to go back to the original name
rename 's/tmp-//' *
답변3
아이디어는 다음과 같습니다.
- 원래 이름 목록을 얻으십시오. 구하다.
- 목록의 스크램블 버전을 저장합니다(
sort -R
). - 예를 들어 각 이름에 무언가를 추가하는 등 충돌하지 않는 방식으로 원본 목록을 삭제합니다.
- 손상된 목록을 순서대로 반영하도록 원본 파일을 이동합니다.
- 섞인 원본 목록을 반영하도록 손상된 파일을 이동합니다.
기본 쉘 코드에서 파일 이름에 줄 바꿈이 없다고 가정하면 현재 디렉터리는 셔플의 대상 디렉터리이고 외부 디렉터리는 쓰기 가능합니다.
find . -type f > ../list
< list sort -R > ../shuffled
while read f; do mv "$f" "$f".tmp; done < ../list
exec 3<../shuffled
while read f; do read s <&3; mv "$f".tmp "$s"; done < ../list
exec 3>&-
답변4
이를 수행하는 잘 알려진 명령은 없지만 운 좋게도 쉘 인터프리터는 이 작업과 유사한 작업을 매우 쉽게 수행할 수 있습니다. 예를 들어:
for i in /my/this/dir/*;do mv -vf "$i" "$i.$RANDOM";done
/my/this/dir
디렉터리의 파일은 단계별로 실행되고 mv
이름에 0에서 32767 사이의 난수를 추가하는 (이름 바꾸기) 명령이 실행됩니다. 예를 들어, 디렉토리에서 이 명령을 실행하면 /sbin
해당 디렉토리의 파일 이름이 다음과 같이 변경됩니다.
ifconfig -> ifconfig.4553
ip -> ip.12767
...
/sbin에서는 이 작업을 수행하지 마십시오. 시스템이 종료됩니다!(하지만 재미있을 것 같아요 :-))
하지만 원하는 것이 아니라면 복원하기가 더 어려울 수 있으니 주의하세요. 따라서 이 스크립트를 실행하기 전에 mv
접두사를 추가하여 테스트 할 수 있습니다 echo
.
for i in /my/this/dir/*;do echo mv -vf "$i" "$i.$RANDOM";done
두 번째 한 줄 스크립트는 아무 작업도 수행하지 mv
않고 echo
.