디렉토리 자체를 포함하지 않고 파일 및 폴더 디렉토리를 어떻게 tar합니까?
나는 일반적으로 :
tar -czvf my_directory.tar.gz my_directory
my_directory에 모든 것 (숨겨진 시스템 파일 포함)을 포함 시키려고하지만 디렉토리 자체는 포함시키지 않으려면 어떻게해야합니까? 나는 원하지 않는다 :
my_directory
--- my_file
--- my_file
--- my_file
내가 원하는:
my_file
my_file
my_file
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd -
한 줄로 작업을 수행해야합니다. 숨겨진 파일에도 잘 작동합니다. "*"는 적어도 bash에서 경로 이름 확장으로 숨겨진 파일을 확장하지 않습니다. 아래는 내 실험입니다.
$ mkdir my_directory
$ touch my_directory/file1
$ touch my_directory/file2
$ touch my_directory/.hiddenfile1
$ touch my_directory/.hiddenfile2
$ cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
$ tar ztf my_dir.tgz
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
-C
tar 스위치를 사용하십시오 .
tar -czvf my_directory.tar.gz -C my_directory .
이 명령 -C my_directory
은 tar에게 현재 디렉토리를로 변경하도록 지시 my_directory
한 다음 .
"현재 디렉토리 전체 추가"(숨겨진 파일 및 하위 디렉토리 포함)를 의미합니다.
수행 -C my_directory
하기 전에 수행 해야합니다. 그렇지 .
않으면 현재 디렉토리에 파일이 있습니다.
평소와 같이 아카이브를 작성하고 다음을 사용하여 추출 할 수도 있습니다.
tar --strip-components 1 -xvf my_directory.tar.gz
--transform
/를 살펴보면 --xform
파일이 아카이브에 추가 될 때 파일 이름을 마사지 할 수 있습니다.
% mkdir my_directory
% touch my_directory/file1
% touch my_directory/file2
% touch my_directory/.hiddenfile1
% touch my_directory/.hiddenfile2
% tar -v -c -f my_dir.tgz --xform='s,my_directory/,,' $(find my_directory -type f)
my_directory/file2
my_directory/.hiddenfile1
my_directory/.hiddenfile2
my_directory/file1
% tar -t -f my_dir.tgz
file2
.hiddenfile1
.hiddenfile2
file1
변환 표현식은의 표현식과 유사 하며 위의 예제에서 ( sed
이외의) 구분 기호를 사용할 수 있습니다 . https://www.gnu.org/software/tar/manual/html_section/tar_52.html/
,
TL; DR
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
일부 조건 (파일, 디렉토리 및 심볼릭 링크 만 아카이브) :
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
설명
아래는 불행히도 ./
아카이브에 상위 디렉토리 가 포함되어 있습니다.
tar -czf mydir.tgz -C /my/dir .
--transform
구성 옵션 을 사용하여 모든 파일을 해당 디렉토리 밖으로 이동할 수 있지만 .
디렉토리 자체를 제거하지는 않습니다 . 명령을 길들이는 것이 점점 어려워지고 있습니다.
magnus 'answer$(find ...)
와 같이 명령에 파일 목록을 추가하는 데 사용할 수 있지만 "파일 목록이 너무 깁니다"오류가 발생할 수 있습니다. 가장 좋은 방법은 다음과 같이 tar 옵션 과 결합하는 것입니다 .-T
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
기본적으로 디렉토리 아래의 모든 파일 ( -type f
), 링크 ( -type l
) 및 하위 디렉토리 ( -type d
)를 나열 하고을 사용하여 모든 파일 이름을 상대적으로 -printf "%P\n"
만든 다음 tar 명령으로 전달하십시오 (을 사용하여 STDIN에서 파일 이름을 가져옵니다 -T -
). -C
옵션은 상대 이름을 가진 파일의 위치 타르가 알 수 있도록 필요합니다. 이 --no-recursion
플래그는 tar가 아카이브하도록 지시 된 폴더로 중복되지 않도록합니다 (중복 파일을 야기 함).
파일 이름으로 특별한 작업을 수행해야하는 경우 (필터링, 심볼릭 링크 등)이 find
명령은 매우 강력 tar
하며 위 명령 의 일부를 제거하여 테스트 할 수 있습니다 .
$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore
예를 들어 PDF 파일을 필터링하려면 추가 ! -name '*.pdf'
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore
비 GNU 찾기
이 명령은 printf
(GNU에서 사용 가능) 사용 하여 상대 경로로 결과를 인쇄하도록 find
지시 find
합니다. 그러나 GNU가없는 경우 find
경로를 상대적으로 만들 수 있습니다 (부모를 제거하십시오 sed
).
find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
이 답변 은 대부분의 상황에서 작동합니다. 그러나 파일 이름이 예를 들어 ./file1
just가 아닌 tar 파일에 어떻게 저장되는지 확인하십시오 file1
. BuildRoot 에서 패키지 파일로 사용되는 tarball을 조작하기 위해이 방법을 사용할 때 문제가 발생한다는 것을 알았습니다 .
한 가지 해결책은 Bash globs를 사용하여 다음을 제외한 모든 파일을 나열하는 것입니다 ..
.
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
이것은 이 답변 에서 배운 트릭 입니다.
이제 tar는 ..?*
또는 일치하는 파일이 없으면 오류를 반환 .[^.]*
하지만 여전히 작동합니다. 오류가 문제인 경우 (스크립트에서 성공을 확인하는 중) 다음과 같이 작동합니다.
shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob
지금은 쉘 옵션을 망쳐 놓고 있지만 *
숨겨진 파일과 일치 하는 것이 더 깔끔하다고 결정할 수 있습니다.
shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob
*
현재 디렉토리에서 쉘이 차지하는 곳에서는 작동하지 않을 수도 있으므로 다음을 사용하십시오.
shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob
cd my_directory
tar zcvf ../my_directory.tar.gz *
유닉스 / 리눅스 시스템이고 숨겨진 파일 (*에서 놓칠 수있는)에 관심이있는 경우 다음을 수행해야합니다.
cd my_directory
tar zcvf ../my_directory.tar.gz * .??*
Windows에서 숨겨진 파일의 모양을 모르겠습니다.
다음 Bash 함수를 제안합니다 (첫 번째 인수는 dir의 경로이고 두 번째 인수는 결과 아카이브의 기본 이름입니다).
function tar_dir_contents ()
{
local DIRPATH="$1"
local TARARCH="$2.tar.gz"
local ORGIFS="$IFS"
IFS=$'\n'
tar -C "$DIRPATH" -czf "$TARARCH" $( ls -a "$DIRPATH" | grep -v '\(^\.$\)\|\(^\.\.$\)' )
IFS="$ORGIFS"
}
이런 식으로 실행할 수 있습니다 :
$ tar_dir_contents /path/to/some/dir my_archive
my_archive.tar.gz
현재 디렉토리 내에 아카이브를 생성합니다 . 숨겨진 (. *) 요소 및 파일 이름에 공백이있는 요소와 함께 작동합니다.
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..
이것은 나를 위해 일했고 "."라는 루트 디렉토리에 모든 파일을 넣지 않고 모든 숨겨진 파일을 포함합니다. tomoe의 답변 에서처럼 :
pax를 사용하십시오.
Pax는 더 이상 사용되지 않는 패키지이지만 완벽하고 간단한 방식으로 작업을 수행합니다.
pax -w > mydir.tar mydir
내가 찾은 가장 간단한 방법 :
cd my_dir && tar -czvf ../my_dir.tar.gz *
# tar all files within and deeper in a given directory
# with no prefixes ( neither <directory>/ nor ./ )
# parameters: <source directory> <target archive file>
function tar_all_in_dir {
{ cd "$1" && find -type f -print0; } \
| cut --zero-terminated --characters=3- \
| tar --create --file="$2" --directory="$1" --null --files-from=-
}
공백이나 다른 특이한 문자로 파일 이름을 안전하게 처리합니다. 선택적으로 -name '*.sql'
find 명령에 유사하거나 유사한 필터를 추가하여 포함 된 파일을 제한 할 수 있습니다.
tar -cvzf tarlearn.tar.gz --remove-files mytemp/*
폴더가 mytemp 인 경우 위를 적용하면 폴더의 모든 파일을 압축하여 제거하지만 혼자 두십시오.
tar -cvzf tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*
제외 패턴을 지정하고 하위 폴더도 보지 않도록 지정할 수 있습니다
tar -C my_dir -zcvf my_dir.tar.gz `ls my_dir`
'development' 카테고리의 다른 글
무료 모나드는 무엇입니까? (0) | 2020.02.29 |
---|---|
Mobile Safari에서 뷰포트 확대 / 축소를 어떻게 비활성화합니까? (0) | 2020.02.29 |
레일스 라우팅 헬퍼 (예 : mymodel_path (model))를 모델에 사용할 수 있습니까? (0) | 2020.02.29 |
버퍼와 같은 Vim의 탭 사용 (0) | 2020.02.29 |
"심볼을 찾을 수 없음"컴파일 오류는 무엇을 의미합니까? (0) | 2020.02.29 |