Cuplikan Bash untuk memindahkan semua file dalam direktori ke direktori itu


14

Saya memiliki direktori dengan banyak file dan direktori di dalamnya. Untuk merapikannya, saya akan meletakkan semua file itu ke direktori, jadi saya akan melakukan sesuatu seperti ini:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

Namun itu jelas tidak akan berhasil karena itu akan mencoba untuk pindah new_directoryke new_directory. Apakah ada cara sederhana untuk melakukan apa yang saya inginkan dalam satu baris tanpa saya harus menyalin dan menempelkan semua file dan direktori di direktori itu?


3
berfungsi, itu hanya mencetak pesan kesalahan yang tidak dapat memindahkan direktori baru ke dalam dirinya sendiri.
cas

Jawaban:


18

Anda

mv * ./new_directory
perintah sebenarnya akan bekerja; itu hanya akan mencetak peringatan bahwa itu tidak bisa memindahkan direktori itu ke dalam dirinya sendiri.


Masalah 'satu-satunya' dengan ini adalah bahwa jika ekspansi total dari perintah menjadi terlalu panjang (yaitu terlalu banyak file, terlalu panjang nama) ini tidak akan berfungsi lagi.
Niels Basjes

Sebagai catatan tambahan, jika Anda akan melakukan ini dengan a, git mvAnda harus menggunakan -kflag, karena git akan gagal secara default, tidak hanya memuntahkan peringatan. Jadi, Anda harus melakukannya git mv -k * ./new_dir.
Yuval A

11

Oneliner cepat dan kotor.

mv `ls -A | grep -v new_directory` ./new_directory

1
Tidak akan berfungsi: a ls polos tidak akan menampilkan dotfiles.
wzzrd

Poin yang sangat bagus. Memperbaiki itu dengan -a.

2
Jadi alih-alih mencoba mv new_directory ke dirinya sendiri (pertanyaan awal), Anda sekarang mencoba untuk pindah. dan .. ke dalam direktori_baru.
Niels Basjes

2
Terima kasih atas umpan balik Niels. Memperbaikinya dengan yang atas yang menghapus. dan .. dari daftar direktori.

8

Jika Anda hanya mencari file (mis. Bukan direktori), maka

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

adalah solusi paling portabel. Untuk kecepatan, Anda harus memindahkan find dan xargs, dengan -print0 dan -0, tetapi hanya jika Anda memiliki GNU find dan xargs.


3
Menggunakan penemuan GNU yang cukup baru, Anda juga bisa menggunakan \ + bukan \; untuk mengurangi jumlah mv yang kami buat.
wzzrd

Jika Anda mendapatkan GNU, Anda juga dapat menggunakan xargs, yang akan melakukan hal yang sama, dan memungkinkan Anda menjalankan beberapa mv sekaligus dengan flag -p.
Cian

mendinginkan penggunaan find- meskipun aku sudah pasti berada di sistem yang tidak memiliki satu, sedih :(
warren

Betulkah? find (afaik) ditentukan dalam SUS, jadi semuanya harus memilikinya. Satu-satunya masalah adalah apakah itu GNU find (yang memiliki banyak opsi keren yang bagus) atau regular find.
Cian


6

Saat saya mengalami masalah ini, saya telah melakukan salah satu dari yang berikut:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

atau

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

Bentuk kedua mengambil keuntungan dari wildcard melewatkan nama file yang dimulai dengan '.'


Saya lupa kartu liar dilewati file bertitik; terima kasih atas pengingatnya! :)
aemonge

2

bagaimana dengan:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

TKI, jangan pindahkan konten ke direktori baru, tetapi letakkan direktori ini di dalam yang baru.


1

Dengan cara yang mirip dengan jawaban @ Rembrane (meskipun bukan satu-liner):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Ini harus 100% portabel - meskipun findsayangnya tidak ada di sistem Anda.


find diperlukan dalam spesifikasi unix tunggal. Dengan demikian, itu seharusnya tidak pernah absen (bukan bahwa Anda tidak dapat membangun sesuatu tanpa itu. Tapi saya bayangkan itu akan membutuhkan sejumlah usaha yang mengerikan, dan tidak ada sistem vendor yang akan kekurangannya)
Cian

mungkin itu beberapa sysadmin hyper-paranoid yoinking findutils atau yang setara? tidak yakin, tapi aku tahu aku telah lari ke Boxen yang tidak memilikinya :(
warren

1

Saran saya: Seperti yang dinyatakan oleh orang lain

mv * ./new_directory

akan bekerja menemukan IFF total ekspansi cukup pendek.

Selain itu, Anda dapat mencoba yang ini untuk meningkatkan jumlah file yang jauh lebih besar:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

Penjelasan

  1. Daftar semua file.
  2. Kelompok semua nama file menjadi potongan maks 100000 karakter.
  3. Buat satu perintah mv per chunk.

istirahat jika Anda punya spasi di nama file Anda
Cian

Kamu benar. Jadi saya kira ini harus ditambah dengan flag -print0 dan -0 untuk memperbaikinya.
Niels Basjes

Saya sudah mencoba dengan -print0dan -0dan masih istirahat.
Cristian Ciupitu

find: warning: Anda telah menentukan opsi -maxdepth setelah argumen non-opsi -type, tetapi opsinya tidak bersifat posisional (-maxdepth memengaruhi tes yang ditentukan sebelumnya dan juga yang ditentukan setelahnya). Silakan tentukan opsi sebelum argumen lain.
Cristian Ciupitu

1

Menggunakan:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

Dari xargshalaman manual:

-P max-procs

  Run up to max-procs processes at a time;

-1

Untuk menghindari pesan kesalahan dan membuatnya tetap sederhana:

mv *.* ./new_Folder

akan melakukan hal yang sama tetapi menghindari pesan kesalahan (kecuali jika Anda memiliki titik di nama folder Anda, saya kira).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.