Buat subfolder yang sama di folder lain

8

Saya memiliki direktori foodengan subdirektori. Saya ingin membuat nama subdirektori yang sama di direktori lain tanpa menyalin kontennya. Bagaimana saya melakukan ini?

Apakah ada cara untuk mendapatkan lsoutput sebagai daftar ekspansi brace?

havakok
sumber

Jawaban:

11

Coba ini,

cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
  • . -type d Untuk membuat daftar direktori di jalur saat ini secara rekursif.
  • mkdir -p -- /destination/directory/{} buat direktori di tujuan.

Ini bergantung pada findyang mendukung perluasan {}di tengah kata argumen.

Siva
sumber
6
Ini dapat rusak jika ada nama file atau folder di tingkat atas dimulai dengan tanda hubung. Itu juga menghilangkan direktori yang dimulai dengan titik. Akhirnya, ketahuilah bahwa tidak setiap implementasi findmendukung interpolasi {}ke string lain.
roaima
1
Dan itu tidak terlalu scalable - akan butuh banyak waktu jika ada jutaan direktori.
Arkadiusz Drabczyk
6
Jika ada banyak hal di /source/dir/path, maka ini mungkin gagal dengan kesalahan "daftar argumen terlalu panjang" ketika shell mencoba memanggil finddengan perluasan *. Lebih baik gunakan saja di .sana. Juga, sebagian besar findimplementasi memungkinkan {}untuk digunakan bahkan ketika digabungkan dengan string lain, tetapi itu tidak universal.
Kusalananda
1
Anda dapat menggunakan .Alih-alih *dalam hal ini. (Menggunakan xarg untuk kinerja dan keamanan mungkin akan memerlukan skrip eksternal untuk path concatenation)
eckes
24

Menggunakan rsync:

rsync -a --include='*/' --exclude='*' /some/path/dir/ dir

Ini akan menciptakan kembali struktur direktori /some/path/dirseperti dirpada direktori saat ini, tanpa menyalin file apa pun.

Direktori apa pun yang ditemukan di jalur sumber akan dibuat pada target karena pola penyertaan, tetapi hal lain akan dikecualikan. Sebagai efek samping dari penggunaan -a( --archive), Anda akan mendapatkan cap waktu yang sama pada semua subdirektori dalam target seperti pada sumber. Ini juga berfungsi untuk membuat struktur direktori lokal dari direktori jarak jauh (dan sebaliknya).

Kusalananda
sumber
Jawabannya hampir selalu rsync!
Arronical
8

Anda dapat menggunakan finduntuk melintasi struktur sumber dan memanggil mkdirsetiap direktori yang ditemuinya.

Contoh ini, menggunakan find, akan menyalin struktur direktori Anda dari fooke/tmp/another/

( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )

The execLoop membangun set direktori di bawahnya foo, yang kemudian diteruskan ke mkdir. Jika Anda tidak memiliki versi findyang mengerti, +Anda dapat menggunakannya \;dengan biaya efisiensi. Gantikan mkdirdengan echo mkdiruntuk melihat apa yang akan terjadi tanpa benar-benar melakukannya.

roaima
sumber
1
Atau dengan lingkaran yang jelas,... -exec sh -c 'for dirpath do mkdir -p "/some/path/$dirpath"; done' sh {} +
Kusalananda
persis dengan GNU find (4.7.0-git) ini sepertinya tidak berfungsi: find: In ‘-exec ... {} +’ the ‘{}’ must appear by itself, but you specified ‘/tmp/another/{}’(itu bekerja dengan baik -exec ... \;)
ilkkachu
Kusalananda, perbaikan diambil, terima kasih
roaima
Ilkkachu Saya yakin saya telah menguji /path/to/{}tetapi saya sekarang tidak dapat menemukan versi mana pun yang berfungsi sehingga saya telah mengadaptasi solusinya. Terima kasih
roaima
3

Dengan bash shell, Anda bisa memintanya untuk perluasan setiap direktori dengan globstaropsi:

shopt -s globstar

dan kemudian salin direktori dengan lingkaran:

for dir in **/
do
  mkdir -p /path/to/dest/"$dir"
done

... atau jika Anda pikir semuanya akan cocok dalam satu panggilan ke mkdir:

set -- **/
mkdir -- "${@/#//path/to/dest/}"

Itu sintaks bash array yang mengatakan: "ambil setiap elemen $@array dan gantikan awal dari masing-masingnya/path/to/dest/ .

Saya tidak mengetahui cara untuk mendapatkan lsoutput secara langsung sebagai daftar ekspansi brace. Jika Anda mencoba memijat output **/ekspansi menjadi ekspansi brace, Anda harus berhati-hati untuk:

  • lepaskan koma apa pun di output
  • melarikan diri {atau${ urutan
  • memastikan string yang dihasilkan tidak melebihi ruang argumen baris perintah yang tersedia

Saya tidak akan merekomendasikannya.

Jeff Schaller
sumber
2

Pertanyaannya adalah duplikat lintas-situs /superuser/1389580/copy-directory-structure-only-at-year-end

Jenis tugas ini adalah kasus penggunaan klasik untuk mtree:

$ mkdir new-tree
$ mtree -cp old-tree | mtree -tdUp new-tree
.:      modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
./bar missing (created)
./bar/bar2 missing (created)
./bar/bar2/bar3 missing (created)
./bar/bar2/bar3/bar4 missing (created)
./foo missing (created)
./foo/foo2 missing (created)
./foo/foo2/foo3 missing (created)

Di atas membuat semua direktori di bawah new-treeyang ada di bawah old-tree. mtreetidak menetapkan cap waktu pada direktori yang baru dibuat, sehingga pohon yang dihasilkan terlihat seperti ini:

$ find old-tree new-tree -ls
 20147  1 drwx--x---   4 jim   jim   5 Sep 24 14:27 old-tree
 20048  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/foo
 20363  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/foo/file
 20073  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/foo/foo2
 20074  1 drwx--x---   2 jim   jim   3 Sep 24 14:27 old-tree/foo/foo2/foo3
 20365  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/foo/foo2/foo3/file
 20364  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/foo/foo2/file
 20051  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/bar
 20077  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/bar/bar2
 20368  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/bar/bar2/file
 20078  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/bar/bar2/bar3
 20369  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/bar/bar2/bar3/file
 20079  1 drwx--x---   2 jim   jim   3 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4
 20370  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4/file
 20366  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/bar/file
 20362  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/file
134489  1 drwx--x---   4 jim   jim   4 Sep 24 16:34 new-tree
134490  1 drwx--x---   3 jim   jim   3 Sep 24 16:34 new-tree/bar
134491  1 drwx--x---   3 jim   jim   3 Sep 24 16:34 new-tree/bar/bar2
134492  1 drwx--x---   3 jim   jim   3 Sep 24 16:34 new-tree/bar/bar2/bar3
134493  1 drwx--x---   2 jim   jim   2 Sep 24 16:34 new-tree/bar/bar2/bar3/bar4
134494  1 drwx--x---   3 jim   jim   3 Sep 24 16:34 new-tree/foo
134495  1 drwx--x---   3 jim   jim   3 Sep 24 16:34 new-tree/foo/foo2
134496  1 drwx--x---   2 jim   jim   2 Sep 24 16:34 new-tree/foo/foo2/foo3

Jika Anda lebih suka new-treecap waktu cocok dengan yang ada di old-tree, cukup jalankan mtreelagi. Karena direktori sudah ada, mtreeakan mengubah stempel waktu agar sesuai dengan spesifikasi sumber:

$ mtree -cp old-tree | mtree -tdUp new-tree
.:      modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar:    modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2: 
        modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2/bar3: 
        modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2/bar3/bar4: 
        modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo:    modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo/foo2: 
        modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo/foo2/foo3: 
        modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
$ find old-tree new-tree -ls
 20147  1 drwx--x---   4 jim   jim   5 Sep 24 14:27 old-tree
 20048  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/foo
 20363  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/foo/file
 20073  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/foo/foo2
 20074  1 drwx--x---   2 jim   jim   3 Sep 24 14:27 old-tree/foo/foo2/foo3
 20365  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/foo/foo2/foo3/file
 20364  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/foo/foo2/file
 20051  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/bar
 20077  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/bar/bar2
 20368  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/bar/bar2/file
 20078  1 drwx--x---   3 jim   jim   4 Sep 24 14:27 old-tree/bar/bar2/bar3
 20369  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/bar/bar2/bar3/file
 20079  1 drwx--x---   2 jim   jim   3 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4
 20370  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4/file
 20366  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/bar/file
 20362  1 -rw-------   1 jim   jim   0 Sep 24 14:27 old-tree/file
134489  1 drwx--x---   4 jim   jim   4 Sep 24 14:27 new-tree
134490  1 drwx--x---   3 jim   jim   3 Sep 24 14:27 new-tree/bar
134491  1 drwx--x---   3 jim   jim   3 Sep 24 14:27 new-tree/bar/bar2
134492  1 drwx--x---   3 jim   jim   3 Sep 24 14:27 new-tree/bar/bar2/bar3
134493  1 drwx--x---   2 jim   jim   2 Sep 24 14:27 new-tree/bar/bar2/bar3/bar4
134494  1 drwx--x---   3 jim   jim   3 Sep 24 14:27 new-tree/foo
134495  1 drwx--x---   3 jim   jim   3 Sep 24 14:27 new-tree/foo/foo2
134496  1 drwx--x---   2 jim   jim   2 Sep 24 14:27 new-tree/foo/foo2/foo3
Jim L.
sumber