폴더에 다른 파일을 포함하지 않고 하위 디렉터리만 압축할 수 있습니까?

폴더에 다른 파일을 포함하지 않고 하위 디렉터리만 압축할 수 있습니까?

A/B/C예를 들어 이것이 귀하의 홈 디렉토리라고 가정해 보겠습니다 . 해당 디렉터리 내에 C하위 디렉터리와 파일이 있습니다. 하지만 아래와 같이 자신의 이름을 가진 디렉토리만 압축하고 싶습니다.

c 아래의 디렉토리가 Test1 Test2인 경우 - Test1.tar Test2.tar가 되기를 바랍니다.

이것은 Linux 시스템에 있습니다.

답변1

tar인수로 재귀하지 않도록 지시 한 다음 find이를 사용하여 각 디렉터리를 인수로 제공할 수 있습니다. 따라서 다음과 같습니다.

find . -type d -print0 | xargs -0 tar --no-recursion -cf your_tree.tar

이름에 공백이나 기타 특수 문자가 포함된 디렉터리의 문제를 방지하기 위한 -print0것입니다 .-0

아래 설명에서 알 수 있듯이 디렉터리가 많으면 명령줄이 너무 커져서 tar여러 번 호출되게 됩니다. 이 경우 다음을 사용하여 매개변수를 읽을 수 있습니다 --files-from.

find . -type d -print0 | tar --null --no-recursion --files-from - -cf your_tree.tar

편집하다:

위의 내용은 OP가 최상위 디렉토리에 tar 파일 세트를 원한다는 것을 명확히 하기 전에 작성되었습니다. 위의 기술을 사용하여 이를 달성할 수 있다고 생각합니다. 예를 들어:

$ mkdir -vp tree/a/b/c tree/foo/bar/baz                                                                                 
mkdir: created directory ‘tree’
mkdir: created directory ‘tree/a’
mkdir: created directory ‘tree/a/b’
mkdir: created directory ‘tree/a/b/c’
mkdir: created directory ‘tree/foo’
mkdir: created directory ‘tree/foo/bar’
mkdir: created directory ‘tree/foo/bar/baz’
$ touch tree/foo/an_unwanted_file
$ cd tree
/var/tmp/tree
$ for dir in $(find . -maxdepth 1 -type d); do if [ "$dir" != "." ]; then find "$dir" -type d -print0 | tar --null --no-recursion --files-from - -cvf "${dir}.tar"; fi; done
./a/
./a/b/
./a/b/c/
./foo/
./foo/bar/
./foo/bar/baz/
$ tar tvf foo.tar                                                                                                       
drwxr-xr-x andy/andy         0 2018-11-29 12:30 ./foo/
drwxr-xr-x andy/andy         0 2018-11-29 12:30 ./foo/bar/
drwxr-xr-x andy/andy         0 2018-11-29 12:30 ./foo/bar/baz/
$ tree
.
├── a
│   └── b
│       └── c
├── a.tar
├── foo
│   ├── an_unwanted_file
│   └── bar
│       └── baz
└── foo.tar

답변2

for dir in A/B/C/*/; do
    name=$(basename "$dir")
    tar -cv -f "$name.tar" -C A/B/C "$name"
done

이렇게 하면 아래에 각각의 별도(숨겨지지 않은) 하위 디렉터리에 대한 아카이브가 생성됩니다 A/B/C. 아카이브는 현재 디렉터리에 생성됩니다.

-C옵션은 tar다음 파일( $name)에 대한 작업 디렉터리를 설정합니다.

-C "$(dirname "$dir")"대신 -C A/B/C약간 더 일반적인 코드를 사용할 수 있습니다 .


C하위 디렉터리에 아카이브 생성

( cd A/B/C &&
  for dir in */; do
      tar -cv -f "${dir%/}.tar" "$dir"
  done )

전체 명령 주변의 하위 쉘은 쉘/스크립트의 나머지 부분에서 작업 디렉토리가 변경되는 것을 방지하고 ${dir%/}값 끝에 있는 슬래시를 제거합니다 $dir.

불행하게도 이 -C옵션은 지정된 아카이브 파일의 작업 디렉터리에 영향을 주지 않습니다 . 그렇지 않으면 옵션 앞의 비트 -f만 이동할 수 있습니다 .-C-f

또는 첫 번째 루프의 변형으로:

for dir in A/B/C/*/; do
    name=$( basename "$dir" )
    ( cd "$( dirname "$dir" )" && tar -cv -f "$name.tar" "$name" )
done

답변3

다음을 사용하는 것이 좋습니다(저는 가장 오래된 무료 tar 구현의 작성자입니다 star).star

star cf file.tar -find . -type d

이것은 -를 star사용하기 때문에 tar 파일의 모든 이름에 대해 작동합니다.libfind

관련 정보