ディレクトリ自体を含めずに、ファイルとフォルダのディレクトリをtarするにはどうすればよいですか?


382

私は通常、

tar -czvf my_directory.tar.gz my_directory

my_directoryにすべて(非表示のシステムファイルを含む)だけを含め、ディレクトリ自体は含めない場合はどうなりますか?欲しくない:

my_directory
   --- my_file
   --- my_file
   --- my_file

が欲しいです:

my_file
my_file
my_file

それがデフォルトの動作tar -czfですか?私の場合、それはファイルではなくディレクトリを保存するだけです。私tarがディレクトリだけを含むとき、それはそれを含みますが、tar -czfそれはファイルを追加するだけです。
Durga Swaroop 2017年

回答:


233
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd - 

1行で作業を行う必要があります。隠しファイルにも有効です。「*」は、少なくとも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

2
これは、スペースやその他の特殊文字を含むファイルでも機能します。よくやった!
PanCrit 2009年

29
完全ではありません-tarファイルに「。」が含まれています また、file1だけでなく./file1も使用します。以下のmateuszaによる解決策では、タールを外すときに--strip-componentsを使用します。
Ivan

23
@Ivanを次のように置き換える.*、コマンドはcd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..期待どおりに機能します。
匿名の

3
あなたの現在のシェルの作業ディレクトリは変更されませんので、@jmathewまたサブシェルを使用することができます$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
アレック・

私はそれが古い答えであることを知っていますがcd、ディレクトリに出入りするのはかなり不十分です。少なくとも、使用時でしたpushdし、popd場合tarなどのいずれかのフラグを持っていませんでした-C
Andris

667

-Ctar のスイッチを使用します。

tar -czvf my_directory.tar.gz -C my_directory .

-C my_directory現在のディレクトリを変更するにはタールを伝えmy_directory、その後、.(隠しファイルとサブディレクトリを含む)「全体カレントディレクトリを追加」を意味します。

実行する-C my_directory前に必ず実行してください。そうしない.と、現在のディレクトリにファイルが取得されます。


5
+1ありがとうございます!それはいまいましい '。' 行方不明でした。とても悪化
JCotton

14
「ほとんどのオプションとは異なり、-Cは、それが処理するファイルのリスト内で発生時点で処理され、次のコマンドを考えてみます。 tar --create --file=foo.tar -C /etc passwd hosts -C /lib libc.aapl.jhu.edu/Misc/Unix-info/tar/tar_65.html 私はいつも試すtar -czvf my_directory.tar.gz * -C my_directoryとそれは機能しません。-C場所は重要です!くそ
ータール

57
完全ではありません-tarファイルに「。」が含まれています また、file1だけでなく./file1も使用します。以下のmateuszaによる解決策では、タールを外すときに--strip-componentsを使用します。
Ivan

3
@Superole:シェルはtarを実行する前にワイルドカードを置き換えます。同様*にワイルドカードを使用すると、隠しファイルが含まれないことに注意してください(元の要件でした)。
dubek 2013年

28
作成します。.tar.gzのルートディレクトリとして。
匿名の

59

通常どおりアーカイブを作成し、次のコマンドで抽出することもできます。

tar --strip-components 1 -xvf my_directory.tar.gz

3
このソリューションは、すべての要件が判明する前に作成されたtarballで作業している状況で特に役立ちます...
Digger

2
マインド--strip-componentsGNUの拡張です。
zneak 2018

2
この回答は、「通常どおり」の例をコンテキストで提供することで改善できます。
Josh Habdas

33

--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/,


3
私はこれをします。それ以外は単なるハックです!
jwg

2
これははるかに優れたソリューションです。
leesei

これが最良の解決策です。
16

1
良い解決策ですが、それが原因となる可能性がありfile list too longます。私のソリューションはそれを防ぎ、より柔軟です。
aross

これは素晴らしいソリューションです。--xform複数のパスに複数回渡すこともできます。
1

26

TL; DR

find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

いくつかの条件がある場合(ファイル、dirs、symlinksのみをアーカイブ)

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構成オプションを使用して、そのディレクトリからすべてのファイルを移動できますが、.ディレクトリ自体は削除されません。コマンドを飼いならすことがますます困難になります。

$(find ...)コマンドにファイルリストを追加するために使用できます(magnusの回答のように)が、「ファイルリストが長すぎます」エラーが発生する可能性があります。最善の方法は-T、次のようにtarのオプションと組み合わせることです。

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オプションが必要なのは、相対名のファイルがどこにあるかをtarが認識できるようにするためです。--no-recursionフラグは、タールは、それが(重複ファイルを引き起こす)アーカイブに語られているフォルダに再帰しないようにです。

ファイル名で特別なことを行う必要がある場合(フィルタリング、シンボリックリンクの追跡など)、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 -

2
すばらしい答えです。非常に精巧で、最も重要なのは、問題を完全に解決することです。
アレックス

16

この回答はほとんどの状況で機能します。ただし、ファイル名がとしてで./file1はなく、たとえばtarファイルにどのように格納されているかに注意してくださいfile1。この方法を使用して、BuildRootでパッケージファイルとして使用されているtarballを操作すると、問題が発生することがわかりました。

1つの解決策は、いくつかのBashグロブを使用して、次の..ようなものを除くすべてのファイルをリストすることです。

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

1
tar: start.sh: Cannot stat: No such file or directoryこれを行うと奇妙なエラーが発生しますこれは現在のディレクトリ内のすべてのファイルで発生します!どうすればこれを回避できますか?
BrainStone 2013年

@BrainStoneまったく同じ結果が得られます。
mbmast 16

15
cd my_directory
tar zcvf ../my_directory.tar.gz *

2
Halは隠しファイルについて明示的に尋ねました。。?? *も必要です。
PanCrit

2
-1:これは隠しファイルをtarに追加しません。tbmanの回答を参照してください。
dubek

3

それがUnix / Linuxシステムであり、隠しファイル(*によって失われる)に関心がある場合は、次のことを行う必要があります。

cd my_directory
tar zcvf ../my_directory.tar.gz * .??*

Windowsでどの隠しファイルがどのように見えるかわかりません。


2

私は次のBash関数を提案します(最初の引数はdirへのパス、2番目の引数は結果のアーカイブのベース名です):

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現在のディレクトリ内にアーカイブを生成します。これは、非表示(。*)要素およびファイル名にスペースが含まれる要素で機能します。


2
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..

これは私にとってはうまくいき、すべてのファイルを「。」というルートディレクトリに置くことなく、すべての隠しファイルが含まれています。ともえの答えのように:


1
tar.create() {
        local folder="${1}"

        local tar="$(basename "${folder}")".tar.gz

        cd "${folder}" && tar -zcvf "../${tar}" .; cd - &> /dev/null
}

例:

tar.create folder

どういたしまして。


1

これが私にとってうまくいきます。

tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')

あなたも使うことができます

tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')

最初のコマンドで、findmy_dirのファイルとサブディレクトリのリストを返します。ただし、ディレクトリmy_dir自体はそのリストに「。」として含まれています。-printfパラメータは、その含む完全なパスを削除します「」そしてまた、すべて しかし printfのフォーマット文字列'%P'は、my_dirのファイルおよびサブディレクトリのリストに残りを残し、検索結果の先頭のスペースで確認できますコマンドの。

これはTARの問題ではありませんが、これを修正したい場合は、2番目のコマンドのように-mindepth 1を追加します。


0

paxを使用します。

Paxは廃止されたパッケージですが、完全にそして単純な方法で仕事をします。

pax -w > mydir.tar mydir

最も実用的で仕事をします+1
Breno Salgado 2013

このコマンドは、次の内容のmydir.tarを作成します:mydir / file1 mydir / file2。
アレックス

0

私が見つけた最も簡単な方法:

cd my_dir && tar -czvf ../my_dir.tar.gz *


1
これには隠しファイルは含まれません。
asynts

0
# 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コマンドに追加して、含まれるファイルを制限できます。


-1
 tar -cvzf  tarlearn.tar.gz --remove-files mytemp/*

フォルダーがmytempの場合、上記を適用すると、フォルダー内のすべてのファイルが圧縮されて削除されますが、そのままにされます。

 tar -cvzf  tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*

除外パターンを指定し、サブフォルダーも調べないように指定することもできます


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.