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