전체 크기와 그 안에 있는 파일 수에 따라 디렉터리를 이동합니다.

전체 크기와 그 안에 있는 파일 수에 따라 디렉터리를 이동합니다.

모든 음악 폴더를 정리하려고 합니다(음악 폴더가 많습니다). 그러나 삭제하는 대신 비어 있거나 몇 Mb만 있거나 파일이 몇 개만 있는 폴더를 이동하고 싶습니다.

find다음 명령을 사용하여 모든 빈 디렉터리를 이동 했습니다 .

find . -empty -type d -exec mv {} /share/Container/beetsV2/music/my_empty_folders \;

...하지만 크기에 따라 디렉토리를 찾는 방법을 알 수 없는 것 같습니다. 나는 다음이 효과가 있을 것이라고 생각했지만 예상보다 더 많은 성과를 거두는 것 같습니다.

find . -size -5M -type d -exec mv {} /share/Container/beetsV2/music/my_folders_under_5Mb \;

몇 개의 파일만 포함된 디렉토리를 찾을 때 위의 작업을 수행하는 단일 명령줄을 찾을 수 없는 것 같습니다. 존재합니까?

답변1

에서 man find:

-size n[cwbkMG] 파일은 반올림하여 n 단위보다 작거나 크거나 정확히 n 단위의 공간을 사용합니다.

이 스위치는 디렉터리와 아무 관련이 없습니다.디스크 사용량.


해결 방법은 다음을 bash사용하여 find출력의 모든 디렉터리를 처리 하는 것입니다 mv.

move_dirs_smaller_than() {
    export MAX=$(($1*1024)) # $1 is in MiB
    export path=$2          # $2 /path must be outside of .
    find . -mindepth 1 -type d -exec bash -c '
        read size _ < <(du -sk "$1")
        ((size < MAX)) && echo mv -- "$1" "$path"
    ' bash {} \; -prune
}

echo출력이 충분히 좋아 보이면 명령문을 제거하십시오.

5MiB의 기능 사용법:

/path~해야 한다아니요현재 디렉터리에서(또는 사용 find ! ./dir):

move_dirs_smaller_than 5 /path

find관련 매뉴얼 페이지를 확인 -prune하고 필요에 따라 -mindepth작성하십시오 .-maxdepth

답변2

GNU 구현은 du다음 보고서를 제공할 수 있습니다.

  • 누적 디스크 사용량(기본값)
  • 누적 크기 대--apparent-size
  • 누적 파일 수(모든 유형)--inode

목차와 그 내용(안타깝게도 하나의 보고서에 세 가지를 모두 포함할 수는 없습니다).

-l/remove 중복 하드 링크를 사용하지 않도록 지시할 수도 있습니다 --count-links.

NUL로 구분된 레코드를 출력하는 -0/ 옵션이 있어 안정적으로 출력 후처리가 가능한 몇 안 되는 제품 중 하나입니다 .--null

따라서 GNU 시스템을 사용하는 경우 다음과 같이 할 수 있습니다.

xargs -r0a <(
  du --inode --null --count-links | # count inodes
    tac -s '' | # reverse the output so parents are shown before children
    perl -0lnse '
      if (
        m{^(\d+)\t(.*)}s &&
        $1 < $max &&
        rindex($2, "$last_moved/", 0) < 0 # not a subdirectory of the last moved
      ) {
        print($last_moved = $2);
      }' -- -max=10
  ) echo mv -it /path/to/destination --

이렇게 하면 (재귀적으로) 10개 미만의 파일이 포함된 디렉터리(디렉터리뿐만 아니라 디렉터리 자체도 포함하여 모든 유형)가 이동됩니다.

파일 수보다는 누적 크기를 고려하여 대체 (또는 단축) --inode합니다 . 디스크 사용량과 동일합니다 (알맞게 업데이트해야 함 ).--apparent-size --block-size=1-b--apparent-size-max

결과가 만족스러우면 삭제 echo하여 실제로 실행해 보세요.

모두 -r, -0, -a, --inode, --apparent-size, -l, , 은 비표준 GNU 확장이며, 그 중 일부는 이러한 표준 유틸리티의 다른 구현에 추가되었으므로 GNU를 설치 --count-links마십시오 . 거기. linux 태그를 사용했기 때문에 GNU 시스템을 사용하고 있을 가능성이 높습니다.tac-b--block-size-tcoreutilsfindutils

파일 수와 누적 크기를 계산하려면 파일 유형과 크기를 보고하고 이를 수동으로 합산하는 조건자가 find있는 GNU를 사용할 수 있습니다.-printf

xargs -r0a <(
  find . -depth -printf '%y %s %p\0' | perl -0lsne '
    if (m{^(\S+) (\d+) ((.*)/.*)}s) {
      my ($type, $size, $file, $parent) = ($1, $2, $3, $4);
      $count{$parent} += ++$count{$file};
      $size{$parent} += $size{$file} += $size;
      unshift @dirs, $file if $type eq "d";
    }
    END {
      for $dir (@dirs) {
        if (
          $size{$dir} < $max_size &&
          $count{$dir} < $max_count &&
          rindex($dir, "$last_moved/", 0) < 0
        ) {
          print $last_moved = $dir;
        }
      }
    }' -- -max_count=10 -max_size="$(( 5 * 1024 * 1024 ))"
  ) echo mv -it /path/to/destination --

겉보기 크기가 아닌 디스크 사용량의 경우 디스크 사용량을 바이트 단위로 얻으려면 512( 위에서 대체됨)를 곱해야 합니다 %s.%b$2$2 * 512

관련 정보