私は通常、次のことを行います。
tar -czvf my_directory.tar.gz my_directory
ディレクトリ自体ではなく、すべて (非表示のシステム ファイルを含む) を my_directory に含めたい場合はどうすればよいでしょうか? 私はほしくない:
my_directory
--- my_file
--- my_file
--- my_file
私が欲しい:
my_file
my_file
my_file
-C
tarのスイッチを使用します。
tar -czvf my_directory.tar.gz -C my_directory .
は-C my_directory
、現在のディレクトリを に変更するように tar に指示しmy_directory
、.
「現在のディレクトリ全体を追加する」(隠しファイルとサブディレクトリを含む) ことを意味します。
そうしない-C my_directory
と.
、現在のディレクトリにファイルが取得されます。
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
通常どおりアーカイブを作成し、次のコマンドで解凍することもできます。
tar --strip-components 1 -xvf my_directory.tar.gz
./
、いいえ./file1
!)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
ません。.
コマンドを飼いならすことはますます難しくなります。
$(find ...)
コマンドにファイル リストを追加するために使用できますが( magnus' answer のように)、「ファイル リストが長すぎます」というエラーが発生する可能性があります。-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
フラグは、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
このコマンドは、結果を相対パスで出力するように指示する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
単にfile1
. このメソッドを使用して、 BuildRootでパッケージ ファイルとして使用される tarball を操作すると、これが問題を引き起こすことがわかりました。
1 つの解決策は、いくつかの Bash glob を使用して、次の..
ようなものを除くすべてのファイルを一覧表示することです。
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
Unix/Linux システムで、隠しファイル (* によって見落とされる) が気になる場合は、次のことを行う必要があります。
cd my_directory
tar zcvf ../my_directory.tar.gz * .??*
Windows で隠しファイルがどのように見えるかわかりません。
cd DIRECTORY
tar -czf NAME.tar.gz *
アスタリスクには、非表示のものも含めてすべてが含まれます
これは私にとってうまくいくものです。
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 ')
最初のコマンドで、findはmy_dirのファイルとサブディレクトリのリストを返します。ただし、ディレクトリmy_dir自体は「.」としてそのリストに含まれています。-printfパラメーターは、「.」を含むフル パスを削除します。また、すべてのcrlf ただし、printfのフォーマット文字列'%P' のスペースは、 my_dirのファイルとサブディレクトリのリストに残り、 findコマンドの結果の先頭のスペースで確認できます。
これは TAR では問題になりませんが、これを修正する場合は、2 番目のコマンドのように-mindepth 1を追加します。
# 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 コマンドに追加して、含まれるファイルを制限することができます。
パックスを使用。
Pax は非推奨のパッケージですが、完璧にシンプルな方法で機能します。
pax -w > mydir.tar mydir
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`