TL; DR
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Dengan beberapa kondisi (arsipkan hanya file, dir, dan symlink):
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Penjelasan
Sayangnya di bawah ini termasuk direktori induk ./dalam arsip:
tar -czf mydir.tgz -C /my/dir .
Anda dapat memindahkan semua file dari direktori itu dengan menggunakan --transformopsi konfigurasi, tetapi itu tidak menghilangkan .direktori itu sendiri. Menjadi semakin sulit untuk menjinakkan perintah.
Anda bisa menggunakan $(find ...)untuk menambahkan daftar file ke perintah (seperti dalam jawaban magnus ' ), tetapi itu berpotensi menyebabkan kesalahan "daftar file terlalu lama". Cara terbaik adalah menggabungkannya dengan -Topsi tar , seperti ini:
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
Pada dasarnya apa yang dilakukannya adalah mencantumkan semua file ( -type f), tautan ( -type l) dan subdirektori ( -type d) di bawah direktori Anda, buat semua nama file relatif menggunakan -printf "%P\n", dan kemudian sampaikan ke perintah tar (dibutuhkan nama file dari STDIN menggunakan -T -). The -Copsi diperlukan agar tar tahu di mana file dengan nama yang relatif berada. The --no-recursionbendera adalah agar tar tidak recurse ke folder itu diperintahkan untuk arsip (menyebabkan file duplikat).
Jika Anda perlu melakukan sesuatu yang istimewa dengan nama file (memfilter, mengikuti symlinks dll), findperintahnya cukup kuat, dan Anda dapat mengujinya dengan hanya menghapus tarbagian dari perintah di atas:
$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore
Misalnya jika Anda ingin memfilter file PDF, tambahkan ! -name '*.pdf'
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore
Temuan non-GNU
Perintah ini menggunakan printf(tersedia di GNU find) yang memberitahu finduntuk mencetak hasilnya dengan jalur relatif. Namun, jika Anda tidak memiliki GNU find, ini berfungsi untuk membuat jalur relatif (menghilangkan orang tua dengan 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 -
tar -czf? Dalam kasus saya ini hanya menyimpan file dan bukan direktori. Ketika saya hanyatardirektori itu termasuk tetapi dengantar -czfitu hanya menambahkan file.