Bagaimana cara memindahkan semua file dalam direktori (termasuk yang tersembunyi) ke direktori lain?
Misalnya, jika saya memiliki folder "Foo" dengan file ".hidden" dan "notHidden" di dalam, bagaimana cara memindahkan kedua file ke direktori bernama "Bar"? Berikut ini tidak berfungsi, karena file ".hidden" tetap di "Foo".
mv Foo/* Bar/
Cobalah sendiri.
mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
Jawaban:
Zsh
atau
(Biarkan
(N)
jika Anda tahu direktori tidak kosong.)Pesta
Ksh93
Jika Anda tahu direktori tersebut tidak kosong:
Standar (POSIX) sh
Jika Anda ingin membiarkan
mv
perintah mengembalikan status kesalahan meskipun berhasil, itu jauh lebih sederhana:GNU find dan GNU mv
Temuan standar
Jika Anda tidak keberatan mengubah ke direktori sumber:
Berikut ini lebih detail tentang cara mengendalikan apakah file dot dicocokkan dengan bash, ksh93 dan zsh.
Pesta
Setel
dotglob
opsi .Ada juga
GLOBIGNORE
variabel yang lebih fleksibel , yang dapat Anda atur ke daftar pola wildcard yang dipisahkan oleh usus besar untuk diabaikan. Jika tidak disetel (pengaturan default), shell berperilaku seolah-olah nilainya kosong jikadotglob
diatur, dan seolah-olah nilainya adalah.*
jika opsi tidak disetel. Lihat Ekspansi Nama File di manual. Direktori meresap.
dan..
selalu dihilangkan, kecuali jika.
dicocokkan secara eksplisit oleh pola.Ksh93
Atur
FIGNORE
variabelnya . Jika tidak disetel (pengaturan default), shell berperilaku seolah-olah nilainya.*
. Untuk mengabaikan.
dan..
, mereka harus dicocokkan secara eksplisit (manual dalam ksh 93s + 2008-01-31 menyatakan bahwa.
dan..
selalu diabaikan, tetapi ini tidak dengan benar menggambarkan perilaku aktual).Anda dapat memasukkan file dot dalam suatu pola dengan mencocokkannya secara eksplisit.
Agar ekspansi keluar kosong jika direktori kosong, gunakan
N
opsi pencocokan pola:~(N)@(*|.[^.]*|..?*)
atau~(N:*|.[^.]*|..?*)
.Zsh
Setel
dot_glob
opsi ..
dan..
tidak pernah cocok, bahkan jika polanya cocok dengan pemimpin.
secara eksplisit.Anda dapat menyertakan file dot dalam pola tertentu dengan
D
kualifikasi glob .Tambahkan
N
kualifikasi glob untuk membuat ekspansi keluar kosong di direktori kosong:*(DN)
.Catatan: Anda mungkin mendapatkan hasil ekspansi nama file dalam urutan yang berbeda (misalnya,
none
diikuti oleh.one
diikuti oleh..two
) berdasarkan pengaturan Anda dariLC_COLLATE
,LC_ALL
, danLANG
variabel.sumber
nullglob
? Akan lebih masuk akal untuk membatalkanmv
perintah (seperti ikan, csh / tcsh, zsh (tanpa(N)
) lakukan, atau bash dengan failglob) daripada menjalankanmv /Bar/
perintah yang tidak masuk akal..
dan..
tidak pernah cocok (seperti di shell yang masuk akal lainnya seperti zsh, fish, pdksh, dan turunannya) bahkan jika Anda mematikan dotglob setelah itu. (GLOBIGNORE=:; shopt -u dotglob; echo .*
tidak akan menampilkan.
dan..
). pengaturan GLOBIGNORE untuk.:..
atau.
atau:
memiliki efek yang sama.ksh93
selalu mengabaikan.
dan..
tampaknya telah rusak di antaraksh93k+
(di mana ia bekerja) danksh93m
(di mana itu tidak lagi berfungsi). Perhatikan bahwa ini buruk karenaksh93
akan mengambil nilai FIGNORE dari lingkungan, jadiFIGNORE='!(..)'
env var misalnya dapat membuat kekacauan.Dari
man bash
sumber
mv
mengeluh bahwa file yang dipanggilFoo/*
tidak ada. Menariknya, jikaFoo
dapat dicari, tetapi tidak dapat dibaca, dan ada file yang dipanggil*
di sana, Anda tidak akan mendapatkan kesalahan, file itu akan dipindahkan, tetapi tidak yang lain dalam direktori.bash
memilikifailglob
opsi sehingga berperilaku lebih sepertizsh
,fish
ataucsh
/tcsh
dan membatalkan perintah dengan kesalahan ketika gumpalan tidak dapat diperluas, bukan itu perilaku palsu meninggalkan gumpalan apa adanya.Cara sederhana untuk melakukan ini
bash
adalahTetapi ini juga akan memindahkan direktori.
Jika Anda ingin memindahkan semua file termasuk tersembunyi tetapi tidak ingin memindahkan direktori apa pun, Anda dapat menggunakan for for dan uji.
for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;
sumber
Salah satu caranya adalah menggunakan
find
:The
-type f
membatasi perintah find untuk mencari file. Anda harus menyelidiki-type
,-maxdepth
dan-mindepth
pilihan darifind
untuk menyesuaikan perintah Anda ke akun untuk subdirektori. Temukan memiliki halaman manual yang panjang tapi sangat membantu .sumber
Foo/
, bukan subdirektori dan file lainnya.Coba perintah salin
cp
:cp -r
berarti salin rekursif, sehingga semua folder dan file akan disalin.Anda dapat menggunakan perintah
rm
hapus untuk menghapus folder:Lihat lebih lanjut: pindahkan semua file dari direktori ke yang lain .
sumber
Rsync adalah pilihan lain:
Ini berfungsi karena di rsync trailing slash penting,
sourcedirectory/
merujuk pada isi direktori, sementarasourcedirectory
akan merujuk ke direktori itu sendiri.Kerugian dari metode ini adalah rsync hanya akan membersihkan file setelah pindah, bukan direktori. Jadi Anda dibiarkan dengan pohon direktori sumber kosong. Untuk pemecahannya, lihat:
Pindahkan file dan hapus direktori dengan rsync?
Jadi, meskipun ini mungkin tidak optimal untuk memindahkan operasi, ini bisa sangat berguna untuk operasi penyalinan.
sumber
Jawaban untuk bash / ikan
Berikut cara untuk melakukannya menggunakan wildcard:
.[!.]* ..?*
akan cocok dengan semua file yang tersembunyi kecuali.
dan..
.[!.]* ..?* *
akan cocok dengan semua file (tersembunyi atau tidak) kecuali.
dan..
Dan untuk menjawab contoh khusus dari pertanyaan ini, Anda perlu
cd foo && mv .[!.]* ..?* * ../bar
Penjelasan
.[!.]*
cocok dengan nama file yang dimulai dengan satu titik, diikuti oleh karakter apa pun kecuali titik yang secara opsional diikuti oleh string apa pun. Ini cukup dekat tetapi melewatkan file dimulai dengan dua titik seperti..foo
. Untuk menyertakan file seperti kita menambahkan..?*
yang cocok berkas-nama dimulai dengan dua titik, diikuti oleh karakter apapun, opsional diikuti beberapa string.Uji
Anda dapat menguji wildcard ini dengan perintah di bawah ini. Saya sudah mencoba mereka dengan sukses di bawah bash dan ikan. Mereka gagal di bawah sh, zsh, xonsh.
sumber
Anda mungkin juga dapat menemukan dan menerima backquotes untuk memilih file untuk perintah pindah. Pindahkan itu ke mv.
Yaitu Untuk file tersembunyi
Begitu
Memindahkan hanya file tersembunyi yang dipilih ke
Bar
:Memindahkan semua file di Foo ke Bar sejak '.' dalam perintah egrep bertindak sebagai wildcard tanpa tanda kurung.
The
^
karakter memastikan pertandingan dimulai dari awal baris.Beberapa detail
egrep
pencocokan pola dapat ditemukan di sini .Menggunakan
maxdepth 1
stop ditemukan dari masuk ke subdirektori.sumber
Terinspirasi dari jawaban ini :
Tanpa menyalin file ...
Peringatan:
--link-dest
path harus absolut atau relatif terhadap TUJUAN (Bar
dalam contoh)Anda harus menggunakan
/
SOURCE (Foo/
dalam contoh), jika tidak maka akan menyalin folder SOURCE alih-alih kontennya.sumber
Saya menemukan bahwa ini bekerja dengan baik untuk bash dan tidak perlu mengubah opsi shell
SUNTING:
Jadi seperti yang dikatakan G-man, jawaban asli saya tidak sesuai dengan posix dan hampir sama dengan jawaban ndemou di atas dengan satu perubahan, yaitu menggunakan ekspansi brace untuk membuat daftar string yang kemudian ditindaklanjuti. Ini berarti Anda tidak perlu
cd
masuk ke direktori sumber. Sebenarnya bukan perubahan besar, tetapi berbeda.contoh: katakanlah Anda sudah memiliki tata letak berikut.
Pertanyaan asli hanya menyebutkan file tersembunyi dengan satu periode, tetapi katakanlah ada beberapa dengan dua atau lebih periode di awal nama. Anda bisa menambahkan ekspresi tambahan ke dalam kawat gigi. Kami kemudian dapat mengeksekusi
Ini akan diperluas ke yang berikut:
Anda sekarang akan melihat semua file yang terletak di destdir :
Anda dapat melakukan beberapa hal keren dengan kawat gigi di bash dengan tambahan lebih banyak lagi di 4.x. Lihat bash-hacker untuk beberapa contoh bagus.
sumber
..
, dan (2) agar sesuai dengan POSIX , Anda harus menggunakannya!
sebagai ganti^
; yaitu{*,.[!.]*}
,.cd
masuk ke direktori sumber untuk bertindak pada file atau menulis path file yang sama berulang-ulang untuk mengekspresikan path ke semua file. Saya akan memperbarui contoh ini segera untuk memberi pembaca gambaran yang lebih baik tentang apa yang saya bicarakan.Untuk distro Linux minimal , berikut ini harus bekerja. Pertama, lakukan pemindahan dasar semua (yang merindukan file tersembunyi). Kemudian, pindahkan semua file yang tersembunyi (termasuk
.
dan..
yang akan sebenarnya tidak akan dipindahkan).Catatan: Jika tidak ada konten yang terlihat, perintah pertama akan menghasilkan pesan kesalahan. Perintah kedua akan selalu menghasilkan kesalahan yang mengatakan itu tidak bisa bergerak
.
dan..
. Dengan demikian, hanya pipa kesalahan ke/dev/null
(seperti yang ditunjukkan).Jika Anda membutuhkan ini sebagai satu-liner, cukup gabungkan dengan semi-kolon:
sumber