개수에 따라 파일을 하위 디렉터리로 이동하는 방법은 무엇입니까? [복사]

개수에 따라 파일을 하위 디렉터리로 이동하는 방법은 무엇입니까? [복사]

내 디렉토리에는 약 100,000개의 파일이 있습니다. 상상할 수 있듯이 이것은 이상적인 상황이 아니며 디렉터리를 하위 디렉터리로 분할하고 싶습니다. 하지만 파일 이름 때문에 이름이나 기타 항목을 기준으로 하위 디렉터리에 넣을 수 없으므로 10개의 디렉터리를 만들고 각 디렉터리에 약 1000개의 파일을 넣으려고 합니다. 이를 수행할 수 있는 간단한 bash 명령이나 루프가 있습니까?

답변1

노력하다:

 n=0; for f in *; do d="subdir$((n++ / 1000))"; mkdir -p "$d"; mv -- "$f" "$d/$f"; done

n이동된 파일 수를 추적합니다. 수천 개의 배치로 각 파일은 이름이 지정된 하위 디렉터리에 할당됩니다 subdir$((n++ / 1000)). (필요한 경우 이름 지정을 조정할 수 있습니다.) mkdir -p "$d"아직 생성되지 않은 경우 이 하위 디렉터리를 생성합니다. mv -- "$f" "$d/$f"파일을 이 하위 디렉터리로 전송합니다.

답변2

소스 디렉터리의 파일 수를 고려하면 제안된 해결 방법은 몇 분 정도 걸릴 수 있습니다.

기다리고 싶지 않다면 모든 이동에 대해 프로세스를 생성하지 않는 솔루션을 고려할 수 있습니다.

일괄 이동의 경우 이동과 유사 하다는 사실을 활용할 수 있습니다. cpio즉 , 소스와 대상이 동일한 파일 시스템에 있으면 작업이 빨라지고, 그렇지 않으면 전체 복사본이 생성됩니다.--pass-through--link

달리 mv: 각 소스 파일에 대한 하드 링크가 남지만 작업이 성공하면 cpio -lpd나중에 모두 쉽게 삭제할 수 있습니다.rm -r

디렉터리 분할기의 구현은 다음과 같습니다.

split_dir()(
  local src=$1 nbatches=$2 dest=$3
  local tmpd=
  trap 'rm -rf "$tmpd"' EXIT
  tmpd="$(mktemp -d "$tmpd")"
  find -type f "$src" > "$tmpd/files"
  local nfiles=$(wc -l < "$tmpd/files")
  local batchsz=$((nfiles/nbatches))
  ( cd "$tmpd"; split -l "$batchsz" -d files )
  local i
  for((i=0;i<nbatches;i++)); do
    mkdir -p "$dest/$i"
    < x$i cpio -pdl "$dest/$i"
  done
)

관련 정보