Salin saja folder bukan file?

16

Apakah ada cara untuk menyalin seluruh direktori, tetapi hanya folder? Saya memiliki file yang rusak di direktori saya yang menyebabkan hard disk saya gagal.

Jadi, alih-alih menyalin file yang rusak ke hard disk lain, saya hanya ingin menyalin folder, karena saya punya skrip yang mencari ratusan folder, dan saya tidak ingin harus secara manual membuat semuanya.

Saya memang mencari manual cp, tetapi tidak bisa melihat apa-apa (saya mungkin melewatkannya)

Katakanlah saya memiliki struktur ini pada HDD saya yang gagal:

dir1
    files
    dir2
        files
        files
        dir4
dir3
files

Yang saya inginkan adalah struktur direktori, bukan file sama sekali.

Jadi saya berakhir dengan HDD baru:

dir1
    dir2
        dir4
dir3

Berharap ada yang tahu beberapa trik!

Shannon
sumber
Maksud Anda, Anda hanya ingin menyalin struktur direktori atau apakah Anda hanya ingin mengecualikan file di direktori kerja saat ini (dan semua file lain di subdirektori yang lebih dalam adalah game)?
Oli
Saya telah menambahkan contoh. maaf karena membingungkan
Shannon
1
FYI gunakan rsyncuntuk menyalin struktur direktori DAN mempertahankan izin dan atribut] ( stackoverflow.com/a/9242883/52074 ). Menggunakan polos mkdir -p tidak mempertahankan izin dan atribut .
Trevor Boyd Smith

Jawaban:

15

Jika Anda ingin mencerminkan kerangka direktori dan menyalin tidak ada file:

find -type d -links 2 -exec mkdir -p "/path/to/backup/{}" \;

Apa yang terjadi di sini:

  • Temukan hanya memilih direktori
  • Kami menggunakan -links 2untuk menemukan direktori sedalam mungkin .
  • mkdir -p akan membuat direktori yang hilang di sepanjang jalan.

Saya sudah melakukannya seperti ini daripada find -type d -exec mkdir -p "/path/to/backup/{}" \;karena akan memotong seluruh buttload mkdirpanggilan. Kita dapat dengan cepat membuktikan ini dengan sedikit tes. Inilah pohon tes diikuti oleh apa yang saya berlari untuk membandingkan dua perintah:

$ tree
.
├── dir1
│   ├── dir2
│   │   └── dir3
│   ├── dir7
│   └── dir8
└── dir9
    └── dir0

$ pr -m -t <(find -type d) <(find -type d -links 2)
.                               ./dir1/dir8
./dir1                          ./dir1/dir2/dir3
./dir1/dir8                     ./dir1/dir7
./dir1/dir2                     ./dir9/dir0
./dir1/dir2/dir3
./dir1/dir7
./dir9                  
./dir9/dir0 

Dan itu hanya akan menjadi lebih baik dalam solusi kata-nyata dengan ribuan direktori.

Oli
sumber
Ini saya menjadi noob, namun bagaimana Anda mencari dir lama untuk menyalin ke cadangan? Saya hanya bisa melihat satu jalan di sini
Shannon
Jika Anda tidak menentukan jalur, findgunakan direktori kerja saat ini sebagai titik awal. Jika Anda ingin menggunakan jalur lain gunakan sintaks:find /path/to/search/ -type.....
Oli
Jadi saya mengatur direktori saya ke folder tertentu yang berisi kerangka yang ingin saya salin, jalankan find -type d -exec mkdir -p "/media/jinglez/TVSeries/TV Series"/{}" \;dan semua harus baik-baik saja? Tampaknya akan memakan waktu cukup lama: /
Shannon
Saya menjalankan ini dari terminal normal bukan?
Shannon
1
Keduanya spesifik untuk klausa exec. {} berarti nama file "ditemukan" saat ini dan \; hanyalah jalan keluar untuk mengakhiri klausa. Dengan kelihatannya, ada tambahan "dalam kode Anda hingga tidak baik, saya yakin ... Harus membaca:find -type d -links 2 -exec mkdir -p "/media/jinglez/TVSeries/TV Series/{}" \;
Oli
2

Cukup mudah dilakukan dengan python one-liner:

bash-4.3$ tree
.
├── ABC
├── set_pathname_icon.py
├── subdir1
│   ├── file1.abc
│   └── file2.abc
├── subdir2
│   ├── file1.abc
│   └── file2.abc
└── subdir3
    └── subdir4
        └── file1.txt

4 directories, 7 files
bash-4.3$ python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination
bash-4.3$ tree ~/new_destination
/home/xieerqi/new_destination
├── subdir1
├── subdir2
└── subdir3
    └── subdir4

Sebagai skrip ini dapat ditulis ulang seperti:

#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
    os.makedirs(os.path.join(sys.argv[1],i)) 
Sergiy Kolodyazhnyy
sumber