Pindahkan setiap file yang bukan direktori

14

Saya memiliki direktori yang saya coba bersihkan yang berisi file dan subdirektori. Yang saya coba lakukan adalah sederhana: pindahkan semua file ke direktori lain, tetapi biarkan semua sub-direktori sebagaimana adanya.

Saya sedang memikirkan sesuatu seperti:

mv [*_but_no_dirs] ./other_directory

Sepertinya harus ada cara sederhana untuk melakukan ini dengan wildcard *dan regex ...

Adakah yang punya ide?

Tanda tanya
sumber
1
Jadi pindahkan semua file dalam subfolder, tetapi abaikan saja di subdirektori?
Wilf
@ Willf: Tepat.
Questionmark
2
Di zsh, Anda bisa melakukannya mv **/*(.) ./other_directory- dengan bash Anda harus menggunakan perintah eksternal seperti find.
godlygeek

Jawaban:

12

Regex tidak terlibat di sini. Wildcard di bash (seperti kebanyakan shell lainnya) hanya cocok dengan file berdasarkan nama file, bukan berdasarkan tipe file atau karakteristik lainnya. Ada satu cara untuk mencocokkan berdasarkan jenis: menambahkan /di akhir pola membuatnya hanya cocok dengan direktori atau tautan simbolik ke direktori. Dengan cara ini, Anda dapat memindahkan direktori, lalu memindahkan apa yang tersisa, dan memindahkan direktori kembali - rumit tetapi berfungsi.

tmp=$(TMPDIR=.. mktemp -d)
mv -- */ "$tmp"
mv -- * "$tmp"/other_directory/
mv "$tmp"/* .
rmdir "$tmp"

Cara standar untuk mencocokkan file berdasarkan jenis adalah dengan menelepon find.

find . -name . -o -type d -prune -o -exec sh -c 'mv "$@" "$0"' other_directory/ {} +

Di zsh, Anda dapat menggunakan kualifikasi glob untuk mencocokkan file berdasarkan jenis. The .kualifikasi sesuai file biasa; gunakan ^/untuk mencocokkan semua non-direktori, atau -^/juga untuk menyertakan tautan simbolik ke direktori.

mv -- *(.) other_directory/

Dalam shell apa pun, Anda cukup loop.

for x in *; do
   if ! [ -d "$x" ]; then
     mv -- "$x" other_directory/
   fi
done
Gilles 'SANGAT berhenti menjadi jahat'
sumber
8

Anda bisa menggunakan sesuatu seperti

find . -maxdepth 1 \( ! -type d \) -exec sh -c 'mv  "$@" MYDIR' _ {} \;

Pertama kita gunakan finduntuk melihat hanya di dalam directoy saat ini, kemudian kita mengabaikan direktori dengan menggunakan ! -type d akhirnya kita mengeksekusi shdan memindahkan semuanya ke direktori tujuan. Anda mungkin mencoba {} +pada akhirnya yang akan lebih cepat.

Valentin Bajrami
sumber
2
Sedikit penjelasan, tolong ...
Questionmark
1
@Questionmark Saya sudah memperbarui jawabannya dan menambahkan beberapa penjelasan. Juga, ada baiknya mengunjungi mywiki.wooledge.org/UsingFind
Valentin Bajrami
Mengapa Anda menyarankan, -exec sh -c 'mv "$@" MYDIR' _ {} \;bukan -exec mv {} MYDIR \;? Hanya untuk mendapatkan sesuatu yang dapat disederhanakan dengan mengubah \;ke +? Anda dapat melakukannya dengan -exec mv -t MYDIR {} +formulir.
Scott
@Scott Saya tidak tahu tentang -tbendera itu. Saya juga menjelaskan dalam jawaban bahwa +lebih cepat tetapi tidak semua findversi mendukungnya. Jadi kode di atas cukup kompatibel dengan findshell apa pun yang digunakan.
Valentin Bajrami
1
@ val0x00ff: "... kode di atas cukup kompatibel dengan findshell atau apa pun yang digunakan." Benar, tetapi begitu juga find … -exec mv {} MYDIR \;, dan yang menggunakan sumber daya lebih sedikit daripada … -exec sh -c 'mv "$@" MYDIR' _ {} \;.
Scott
0

Ini berpotensi agak berbahaya tapi

cp * destination/
rm *

Karena cp dan rm tidak akan beroperasi pada direktori tanpa -r switch.

miick
sumber
-1

Saya sarankan hanya melakukan mv *.* destination/dengan tujuan / menjadi folder yang Anda pindahkan.

Peter Z
sumber
2
periksa: unix.stackexchange.com/help/formatting
Jeff Schaller
2
Nama direktori dapat berisi 'titik' dan nama file dapat mengecualikannya (dan sering kali demikian) sehingga *.*akan memindahkan beberapa direktori dan meninggalkan beberapa file, yang bukan yang diinginkan penanya.
dave_thompson_085
Maaf tapi ini sepenuhnya salah. Itu hanya akan memindahkan apa pun dengan titik di namanya dan tidak memindahkan apa pun tanpa satu titik. Dots sama sekali tidak eksklusif untuk file dan mereka juga tidak diharuskan oleh file, jadi ini hanya akan memindahkan pilihan file dan direktori secara acak.
terdon
-2
mv $(ls -l | grep "^-" | awk '{print $9}') ./folder_where_move
sy s
sumber