どのように私は、ディレクトリ自体を含めずにファイルとフォルダのディレクトリタールのですか?

StackOverflow https://stackoverflow.com/questions/939982

  •  06-09-2019
  •  | 
  •  

質問

私は、一般的に行います:

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 - 

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

他のヒント

タールの-Cスイッチを使用します:

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

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

あなたは(中マグナスと答えたのような)コマンドにファイルのリストを追加する$(find ...)を使用することができますが、その潜在的に「ファイルリストが長すぎる」エラーが発生します。最良の方法は、このように、タールの-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)、(それが使用してSTDINからファイル名をとり、相対-printf "%P\n"を使用してすべてのファイル名を作り、その後、tarコマンドにそれを渡すことです-T -)。 -Cオプションは、相対的な名前のファイルが置かれている場所タールが知っているように、必要とされています。 --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に指示find(GNUの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、としてtarファイルに格納されています。私は BuildRoot のパッケージファイルとして使用tarballを操作するために、このメソッドを使用している場合、これは問題を引き起こしたことを発見します。

一つの解決策は、このような..を除くすべてのファイルを表示するために、いくつかのBashグロブを使用することです。

tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *

これは私がをhref="https://stackoverflow.com/a/2910105/991411">です。

..?*または.[^.]*に一致するファイルがない場合は今タールはエラーを返しますが、それはまだ動作します。エラーが問題である場合(スクリプトの成功のためにチェックされている)、これは動作します:

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 *

それはUNIX / Linuxシステムだと、あなたは(*によって見落とされます)隠しファイルを気にしている場合、あなたがする必要があります。

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

私は隠しファイルは、Windowsの下でどのように見えるかを知りません。

私は次のバッシュ関数(最初の引数はディレクトリへのパスであり、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を生成します。それは隠された(。*)要素と、そのファイル名にスペースを持つ要素で動作します。

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

この1は私のために働いて、それが名前のルートディレクトリ内のすべてのファイルを置くことなく、すべての隠しファイルが含まれます「」

の巴の回答するのように

PAXを使用します。

パックスは、廃止予定のパッケージですが、完全かつ簡単な方法で仕事をしていません。

pax -w > mydir.tar mydir

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

CD MY_DIR &&タール-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=-
}

安全スペースやその他の異常な文字を含むファイル名を処理します。あなたは、必要に応じてファイルが含ま制限するために、findコマンドに-name '*.sql'または同様のフィルタを追加することができます。

 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`
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top