하위 폴더가 포함된 여러 수준의 2GB 이미지가 포함된 폴더가 있습니다.
N
tar 파일에 각 (하위) 폴더의 파일 만 보관하고 싶습니다 . find
그때 사용해 보았지만 tail
제대로 tar
작동하지 못했습니다. 내가 시도한 것은 다음과 같습니다(가설 N = 10
).
find . | tail -n 10 | tar -czvf backup.tar.gz
...이 오류를 출력합니다.
Cannot stat: File name too long
어떻게 되어가나요? 생각해 보세요. 작동하더라도 10개 파일이 아닌 모든 폴더의 처음 10개 파일만 압축할 것이라고 생각합니다.각폴더.
N
각 폴더의 파일을 얻는 방법은 무엇입니까 ? (서류주문 불필요)
답변1
pax
이 -0
옵션을 지원 하는 경우 다음을 사용하세요 zsh
.
print -rN dir/**/*(D/e:'reply=($REPLY/*(ND^/[1,10]))':) |
pax -w0 | xz > file.tar.xz
여기에는 목록의 각 디렉터리에 대한 처음 10개의 디렉터리가 아닌 파일이 파일 이름별로 정렬되어 포함됩니다. glob 한정자를 추가하여 다른 정렬 순서를 선택할 수 있습니다 om
(수정 시간별 정렬, Om
역순 정렬), oL
(길이별 정렬), non
(이름별 정렬, 번호별 정렬)...
표준 명령이 없거나 pax
지원되지 않지만 -0
GNU 명령이 있는 경우 tar
다음을 수행할 수 있습니다.
print -rN -- dir/**/*(D/e:'reply=($REPLY/*(ND^/[1,10]))':) |
tar --null -T - -cjf file.tar.xz
해당 권한이 없지만 zsh
액세스 권한 bash
(GNU 프로젝트의 셸)이 있는 경우 다음을 수행할 수 있습니다.
find dir -type d -exec bash -O nullglob -O dotglob -c '
for dir do
set -- "$dir/*"; n=0
for file do
if [ ! -d "$file" ] || [ -L "$file" ]; then
printf "%s\0" "$file"
(( n++ < 10 )) || break
fi
done
done' bash {} + | pax -0w | xz > file.tar.xz
그러나 이렇게 하면 효율성이 크게 저하됩니다.
답변2
/tmp/dir
각 (하위) 폴더의 N(예: N=10) 파일만 단일 파일에 보관하려는 홈 디렉토리가 있다고 가정합니다 backup.tar.gz
.
예 tree
:/tmp/dir
dir/
├── one
│ ├── one10.txt
│ ├── one11.txt
│ ├── one1.txt
│ ├── one2.txt
│ ├── one3.txt
│ ├── one4.txt
│ ├── one5.txt
│ ├── one6.txt
│ ├── one7.txt
│ ├── one8.txt
│ ├── one9.txt
│ └── one_deep
│ ├── one_deep1
│ ├── one_deep10
│ ├── one_deep11
│ ├── one_deep2
│ ├── one_deep3
│ ├── one_deep4
│ ├── one_deep5
│ ├── one_deep6
│ ├── one_deep7
│ ├── one_deep8
│ └── one_deep9
├── three
│ ├── three10.txt
│ ├── three11.txt
│ ├── three1.txt
│ ├── three2.txt
│ ├── three3.txt
│ ├── three4.txt
│ ├── three5.txt
│ ├── three6.txt
│ ├── three7.txt
│ ├── three8.txt
│ ├── three9.txt
│ └── three_deep
│ ├── three_deep1
│ ├── three_deep10
│ ├── three_deep11
│ ├── three_deep2
│ ├── three_deep3
│ ├── three_deep4
│ ├── three_deep5
│ ├── three_deep6
│ ├── three_deep7
│ ├── three_deep8
│ └── three_deep9
암호:
cd /tmp; for i in `find dir/* -type d`; do find $i -maxdepth 1 -type f | tail -n 10 | xargs -I file tar -rf backup.tar file; done; gzip backup.tar
backup.tar.gz
이렇게 하면 10개의 파일이 포함된 하위 폴더가 생성됩니다 /tmp/dir
.
답변3
의 출력은 find
단순하기 때문에 실제로 경로를 보지 않고는 어떤 파일이 동일한 디렉터리에 속하는지 알 수 없습니다. 또 다른 방법은 find
경로를 확인하지 않고 여러 개의 s(각 폴더당 하나씩)를 사용하는 것입니다 . 이것이 제가하는 것입니다. 하위 폴더당 최대 10개의 파일을 압축하려면 다음과 같이 사용하세요.
for dir in $(find . -type d); do
find "$dir" -maxdepth 1 -type f -printf "\"%p\"\n" | tail -10
done | xargs tar cvfz backup.tar.gz
현재 폴더의 모든 디렉터리를 재귀적으로 찾습니다. 각 디렉토리에 대해 최대 10개의 파일을 찾습니다.정확히폴더 ( -maxdepth 1
). 전체 루프가 완료되면 tar
루프에서 출력되는 모든 파일에 대해 명령이 실행됩니다. 또한 해당 옵션을 사용 $dir
하여 find
따옴표 안에 각 파일 이름을 인쇄함으로써 공백이 포함된 디렉터리 및 폴더 이름을 계산했습니다 -printf
.
답변4
디렉터리 이름에 해시를 사용하고 해시 개수가 임계값 미만인 경우에만 파일 이름을 내보냅니다. 예를 들어
find . -depth -type f \
| perl -MFile::Spec -nle '(undef,$d,$f)=File::Spec->splitpath($_); print if $seen{$d}++ < 3' \
| tar ...