현재 디렉터리에서 특정 크기보다 작은 디렉터리를 모두 이동하고 싶습니다.
여기서 저는 다음과 같이 선택했습니다.
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_SIZE
및 BLOCK_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 --
비슷한 휴대용 작업을 수행하려면(장난감 상자 du
1 무시) 다음을 수행할 수 있습니다.
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_SIZE
DU_BLOCK_SIZE
-b
-k
-K
-m
du
²정수 오버플로의 위험이 증가하지만. 512는 일반적으로 최소 공간 할당 단위이므로 디스크에 사용되는 기본 단위로 사용하는 것이 좋습니다.