Pindahkan semua file kecuali satu

155

Bagaimana saya bisa memindahkan semua file kecuali satu? Saya mencari sesuatu seperti:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

di mana saya memindahkan barang lama ke barang baru kecuali folder Tux.png. ! -sign mewakili negasi. Apakah ada alat untuk pekerjaan itu?

Léo Léopold Hertz 준영
sumber

Jawaban:

142

Jika Anda menggunakan bash dan extglobmengatur opsi shell (yang biasanya merupakan kasus):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/
sth
sumber
1
Saya mendapatkan sesuatu yang salah ketika saya menguji perintah untuk banyak item: mv ~ / Linux / Old /! (Tux.png Tux1.png Tux2.png) ~ / Linux / New / Ini mengosongkan seluruh direktori-Old. Apa yang salah?
Léo Léopold Hertz 준영
5
@UnixBasics, coba: ~ / Linux / Old /! (Tux.png | Tux1.png | Tux2.png)
Juliano
@Juliano Perintah yang sangat keren! Apakah ada lebih banyak operasi matematika seperti OR dan XOR? Saya menganggap pipa untuk DAN.
Léo Léopold Hertz 준영
@Juliano Saya agak bingung dengan pola-pola seperti: mv ~ / Linux /? (Tux * .png) ~ / Linux / Baru / mv ~ / Linux / + (Tux * .png) ~ / Linux / New / Pada yang sebelumnya , Saya ingin pindah 0-1 Tux-foto. Pada yang terakhir, saya ingin memindahkan 1-n foto Tux. Mereka pindah semuanya. Mengapa? Apakah mungkin untuk memindahkan sejumlah foto tertentu?
Léo Léopold Hertz 준영
97

Masukkan yang berikut ini ke .bashrc Anda

shopt -s extglob

Itu meluas regex. Anda kemudian dapat memindahkan semua file kecuali satu per satu

mv !(fileOne) ~/path/newFolder

Pengecualian terkait dengan perintah lain

Perhatikan bahwa, dalam menyalin direktori, blitz-maju tidak dapat digunakan dalam nama seperti yang terlihat di utas Mengapa extglob kecuali melanggar kecuali kondisi? :

cp -r !(Backups.backupdb) /home/masi/Documents/

jadi Backups.backupdb/salah di sini sebelum negasi dan saya tidak akan menggunakannya baik dalam memindahkan direktori karena risiko menggunakan salah maka gumpal dengan perintah lain dan kemungkinan pengecualian lainnya.

Léo Léopold Hertz 준영
sumber
3
Ini sebenarnya jawaban yang benar. Punyaku salah; untungnya saya telah menggunakannya dalam folder dengan hanya beberapa file. Berikut ini informasi lebih lanjut tentang metode yang ditunjukkan Masi: wiki.bash-hackers.org/syntax/pattern Buka "Extended pattern language" dan Anda akan menemukan info lebih lanjut tentang ini. Terima kasih kepada @ paul-whittaker karena telah menunjuk masalah ini.
mimoralea
Ini adalah jawaban lama tetapi masih valid. Saya menggunakan Ubuntu 18 dan extglob tampaknya diaktifkan secara default (saya tidak berbelanja). Saya menggunakan perintah berikut untuk memindahkan semua file dalam direktori saat ini ke dalam arsip yang juga ada di dalam direktori ini, TIDAK termasuk folder arsip lain: mv !(arc*) archive_190629b
TonyG
70

Saya akan pergi dengan cara tradisional & xargs:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1membuatnya tidak mencari secara rekursif. Jika Anda hanya peduli tentang file, Anda bisa mengatakannya -type f. -mindepth 1membuatnya tidak menyertakan ~/Linux/Oldjalan itu sendiri ke dalam hasilnya. Bekerja dengan nama file apa pun, termasuk yang berisi baris baru yang disematkan.

Satu komentar mencatat bahwa -topsi mv mungkin merupakan ekstensi GNU. Untuk sistem yang tidak memilikinya

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;
Johannes Schaub - litb
sumber
1
Terpilih karena mendorong belajar alat yang ampuh, temukan. Catatan, untuk file dengan spasi putih ini tidak akan berfungsi. Pertimbangkan "find -print0 | xargs -0" atau abaikan xargs: "find [apa yang Anda katakan] -exec mv -t {} ~ / Linux / New \;"
JasonSmith
Jika perintah mv Anda tidak memiliki opsi -t, maka gunakan "find ... -exec mv {} Linux / New \;" atau "temukan ... | xargs -I {} mv {} Linux / Baru". Opsi -t tampaknya merupakan ekstensi GNU, yang bagus untuk Linux, tetapi mungkin tidak di tempat lain.
Rob Kennedy
jhs, oh saya gagal. entah bagaimana saya pikir xargs terpecah pada baris baru tetapi tidak pada spasi. Sepertinya saya bingung dengan "membaca" :) saya memperbaikinya
Johannes Schaub - litb
Terima kasih banyak atas tipnya yang luar biasa! Saya akan memilih sth karena menargetkan pertanyaan. Namun, saya dapat merasakan manfaat dari perintah Anda nanti, jadi saya harus memilih cara "find and xargs". Itu hanya bebatuan. Terima kasih :)
Léo Léopold Hertz 준영
Cara yang rumit. Jawaban Masi lebih lengkap, lebih mudah dan karenanya lebih benar
user637338
30

Cara cepat adalah dengan memodifikasi nama file tux sehingga perintah pindah Anda tidak akan cocok.

Sebagai contoh:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png
John T
sumber
jangan gunakan " . ", karena itu hanya akan memindahkan file yang memiliki "." dalam nama. Hanya "*" sudah cukup.
Juliano
1
Jika Anda mengubahnya ke * itu akan menghapus file Anda juga.
John T
6
@ John T: Tidak, * glob tidak cocok dengan file yang dimulai dengan titik.
Bill Karwin
Ini adalah jawaban terbaik sejauh ini. Tidak perlu mengubah atau berkomentar jawaban ini. 100 poin. Terima kasih banyak. Sudah selesai dilakukan dengan baik!
Steve K
23

Saya pikir cara termudah untuk dilakukan adalah dengan backticks

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Edit:

Gunakan backslash dengan ls sebagai gantinya untuk mencegah menggunakannya dengan alias, yaitu sebagian besar ls disebut sebagai ls --color.

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Terima kasih @Arnold Roa

Rohail Abbas
sumber
1
Bisakah Anda jelaskan mengapa Anda menggunakannya di grep -vsana?
Léo Léopold Hertz 준영
1
Opsi -v di grep tidak termasuk hasilnya, seperti mengambil semuanya kecuali Tux.png
Rohail Abbas
1
Ini memang intuitif, tetapi jawaban di atas lebih baik. Jika Anda menulis skrip, misalnya, ini mengharuskan Anda untuk berada di direktori yang benar ..
nJGL
@ nJGL Kami juga dapat memberikan jalur absolut di sini, saya menggunakan homedirectory (~) karena pertanyaan memiliki ini
Rohail Abbas
@RohailAbbas Cukup adil. ✌️
nJGL
14

Untuk bash, jawaban pertama benar. Berikut ini sintaks zsh (shell pilihan saya):

mv ~/Linux/Old/^Tux.png ~/Linux/New/

Membutuhkan EXTENDED_GLOBopsi shell untuk diatur.

Juliano
sumber
3
Bagaimana jika kita ingin mengecualikan dua file?
mpen
13

Saya menemukan ini menjadi sedikit lebih aman dan lebih mudah untuk diandalkan untuk gerakan sederhana yang mengecualikan file atau direktori tertentu.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET
alex.pilon
sumber
Ini adalah solusi terbaik untuk Busybox / ASH
Stuart Cardall
1
Ini berfungsi untuk saya dalam situasi di mana saya harus memindahkan semua file kecuali beberapa folder ke direktori lain
Umar Hayat
The -lpilihan untuk lsakan mencakup banyak info yang tidak relevan pada baris perintah dan mengakibatkan kegagalan perintah mv.
jdhao
5

Berikut ini bukan metode yang dijamin 100%, dan tidak boleh dicoba sama sekali untuk skrip. Tetapi beberapa kali itu cukup baik untuk penggunaan shell interaktif cepat. File file glob suka

[abc]*

(yang akan cocok dengan semua file dengan nama yang dimulai dengan a, b atau c) dapat dinegasikan dengan memasukkan karakter "^" terlebih dahulu, yaitu

[^abc]*

Saya terkadang menggunakan ini untuk tidak cocok dengan direktori "lost + found", seperti misalnya:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

Tentu saja jika ada file lain dimulai dengan l saya harus memprosesnya setelah itu.

hlovdal
sumber
4
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

Perintah find mencantumkan semua file biasa dan perintah fgrep menyaring semua Tux.png. Backticks memberitahu mv untuk memindahkan daftar file yang dihasilkan.

David Norman
sumber
4
Tidak pernah, mengevaluasi find sebagai argumen untuk perintah lain. Hal-hal buruk akan terjadi. Anda mungkin baru saja membuat kerentanan. Selalu gunakan find -print0 | xargs -0 membangun, atau menemukan -exec.
Juliano
3

Bagaimana kalau Anda memindahkan semua yang ada di folder dan kemudian hanya memindahkan Tux.png kembali?

Saya tidak bisa memikirkan sintaks shell untuk mengatakan "semuanya kecuali ..." begitu saja.

David Z
sumber
3
ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'
aitor
sumber
1
Perintah ini sepertinya hilang satu bagian dan tidak berfungsi di komputer saya. ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/bekerja sebagai gantinya.
Katherine Chen
3

Bagaimana tentang:

mv $(echo * | sed s:Tux.png::g) ~/Linux/New/

Anda harus berada di folder.

antibus
sumber
3

Orang dapat melewati grep seperti ini:

ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/
Arch Linux Tux
sumber
1

Ini bisa lebih sederhana dan mudah diingat dan itu bekerja untuk saya.

mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

Pakpoom Tiwakornkit
sumber