특정 크기 아래의 모든 디렉터리를 이동하는 방법은 무엇입니까?

특정 크기 아래의 모든 디렉터리를 이동하는 방법은 무엇입니까?

현재 디렉터리에서 특정 크기보다 작은 디렉터리를 모두 이동하고 싶습니다.

여기서 저는 다음과 같이 선택했습니다.

for dir in *
do
    if [[ $(du -s "$dir" | awk '{print $1}') -le 50000 ]]
    then
      ls -l "$dir"
    fi
done

이제 dirname을 사용하여 디렉토리를 가져와야 한다고 생각하지만 어떻게든 내가 무엇을 하든 불평을 합니다. ;)

이를 수행할 수 있는 영리한 방법이 있습니까? ;)

답변1

발품 작업을 올바르게 수행했다고 가정하면 mv 명령의 위치는 ls -l "$dir" 뒤와 "fi" 앞이 됩니다.

예: mv $dir /where/you/want/it/re located

디렉터리 이름에 ""(또는 해당 문제에 대한 기타 특수 문자)가 포함되어 있으면 문제가 발생할 수 있습니다. 이러한 문제가 발생하면 다음과 같이 추가 상담을 받을 수 있습니다.다른 스크립트의 내용으로 사용하기 위해 변수를 이스케이프하세요스레드 영감.

답변2

내가 함께 할게

find . -maxdepth 1 -type d | grep -v ^\\.$ | xargs -n 1 du -s | while read size name ; do if [ $size -le 50000 ] ; then mv "$name" /path/to/target/ ; fi done

현재 디렉터리에서 크기가 50000 미만인 모든 디렉터리를 찾아 대상 디렉터리로 이동합니다.

답변3

다음은 1000KB 미만의 동일한 레벨에 있는 모든 폴더를 이동하는 예입니다.

find . -mindepth 1 -maxdepth 1 -type d -exec bash -c 'if [ $(du -d0 {} | cut -f1) -lt 1000 ];then mv {} SOMEWHERE;fi' \;

답변4

GNU 시스템에서 임의의 디렉토리 이름을 처리하려면 다음을 수행하십시오.

du --block-size=1 -l0d1 |
  perl -0 -lne '
    print $2 if /^(\d+)\t(.*)/s && $2 ne "." && $1 < 50000 * 1024' |
  xargs -r0 mv -vt /destination/directory --

du기본 블록 크기는 512이지만 어떤 du이유로 GNU는 이를 1024로 변경하기로 결정했습니다. 그러나 $POSIXLY_CORRECT환경에 있는 동안 변경되며, DU_BLOCK_SIZEBLOCK_SIZE환경 변수를 통해 BLOCKSIZE변경 될 수도 있습니다.

따라서 명령줄에서 명시적으로 지정하는 것이 좋습니다. 블록 크기가 1이면 바이트 정밀도로 디스크 사용량을 지정할 수 있어 후처리가 더 쉬워집니다².

-d1와 마찬가지로 를 사용하면 --max-depth=1현재 작업 디렉터리의 각 하위 디렉터리와 현재 작업 디렉터리 자체의 디스크 사용량을 얻을 수 있습니다(불행히도 없음 --min-depth). 이는 du모든 디렉터리에서 실행되는 것을 방지할 뿐만 아니라 현재 디렉터리에서 필요하지 않고 $2 ne "."에서 삭제해야 하는 파일의 크기를 계산한다는 의미이기도 합니다 perl. du -- */이는 숨겨진 디렉터리를 건너뛰지 않고 디렉터리에 대한 심볼릭 링크가 처리되지 않는 작업을 실행하는 것보다 이점이 있습니다.

이는 이러한 디렉터리의 재귀 하강에서 발견된 파일에 대한 모든 하드 링크를 계산해야 함을 의미합니다 -l. --count-links그렇지 않으면 특정 파일에 대한 하드 링크가 하위 디렉터리 중 하나에서 발견되면 해당 파일에 대한 다른 하드 링크는 계산되지 않습니다. . 다른 디렉토리에 연결합니다. 이는 또한 주어진 파일에 대한 하드 링크를 의미합니다.같은 하위 디렉토리에du -s또한 모두 계산되므로 단일 디렉터리에서 사용할 때와 다른 값이 나올 수 있습니다.

du따라서 디렉터리 트리에 하드 링크가 포함될 가능성이 있는 경우 각 디렉터리에 대해 하나의 하드 링크를 호출하여 서로 독립적으로 계산되는지 확인하는 것이 좋습니다 .

find . ! -name . -prune -type d -printf '%P\0' |
  xargs -r0 -n1 du --block-size=1 -0s -- |
  perl -0 -lne '
    print $2 if /^(\d+)\t(.*)/s && $2 ne "." && $1 < 50000 * 1024' |
  xargs -r0 mv -vt /destination/directory --

비슷한 휴대용 작업을 수행하려면(장난감 상자 du1 무시) 다음을 수행할 수 있습니다.

for dir in .* *; do
  [ "$dir" = . ] || [ "$dir" = .. ] && continue
  [ -d "$dir" ] || continue
  [ -L "$dir" ] && continue
  du_output=$(
    LC_ALL=C POSIXLY_CORRECT=1 BLOCK_SIZE=512 BLOCKSIZE=512 DU_BLOCK_SIZE=512 du -s -- "$dir"
  ) || continue # don't take any decision if du fails for that dir
  LC_ALL=C awk -- '
    BEGIN {$0 = ARGV[1]; exit !($1 * 512 < 50000 * 1024)}
    ' "$du_output" || continue

  mv -- "$dir" /destination/directory
done

(검증되지 않은).

이 방법은 총 4개의 명령을 실행하는 첫 번째 방법과 mv비교하여 최대 7개의 명령을 실행합니다. (디렉토리 수가 많은 경우 더 많은 명령을 두 번 이상 실행해야 합니다.)파일당그러면 효율성이 훨씬 떨어지게 됩니다.


1 비지박스(busybox) 및 토이박스(toybox)와 같이 주로 Linux용으로 구현된 일부 다른 구현은 du이 분야의 역사적 관행 및 표준을 따르기보다는 GNU를 따르도록 선택했습니다. 최악의 경우 는 "장난감 상자"(예: Android에서 발견됨)로, , , 또는 POSIXLY_CORRECT( 바이트 BLOCKSIZE) , (키비바이트, 기본값), (512), (메비바이트) 옵션을 지원하지 않습니다. 이식 가능한 방식(해당 구현을 고려해야 하는 경우).BLOCK_SIZEDU_BLOCK_SIZE-b-k-K-mdu

²정수 오버플로의 위험이 증가하지만. 512는 일반적으로 최소 공간 할당 단위이므로 디스크에 사용되는 기본 단위로 사용하는 것이 좋습니다.

관련 정보