GNU/Linux >> Belajar Linux >  >> Linux

Mengapa find -exec mv {} ./target/ + tidak berfungsi?

Saya mengalami masalah yang sama di Mac OSX , menggunakan ZSH shell:dalam hal ini tidak ada -t opsi untuk mv , jadi saya harus mencari solusi lain. Namun perintah berikut berhasil:

find .* * -maxdepth 0 -not -path '.git' -not -path '.backup' -exec mv '{}' .backup \;

Rahasianya adalah mengutip kawat gigi . Tidak perlu kawat gigi berada di akhir exec perintah.

Saya menguji di bawah Ubuntu 14.04 (dengan BASH dan ZSH shells), cara kerjanya sama.

Namun, saat menggunakan + tanda, sepertinya memang harus di akhir exec perintah.


Halaman manual (atau manual GNU online) cukup banyak menjelaskan semuanya.

temukan -exec perintah {} \;

Untuk setiap hasil, command {} dieksekusi. Semua kemunculan {} diganti dengan nama file. ; diawali dengan garis miring untuk mencegah shell menafsirkannya.

temukan -exec perintah {} +

Setiap hasil ditambahkan ke command dan dieksekusi sesudahnya. Mempertimbangkan batasan panjang perintah, saya rasa perintah ini dapat dijalankan lebih sering, dengan halaman manual yang mendukung saya:

jumlah total pemanggilan perintah akan jauh lebih sedikit daripada jumlah file yang cocok.

Perhatikan kutipan ini dari halaman manual:

Baris perintah dibuat dengan cara yang hampir sama dengan xargs membuat baris perintahnya

Itu sebabnya tidak ada karakter yang diperbolehkan antara {} dan + kecuali spasi. + make find mendeteksi bahwa argumen harus ditambahkan ke perintah seperti xargs .

Solusinya

Untungnya, implementasi GNU dari mv dapat menerima direktori target sebagai argumen, dengan -t atau parameter yang lebih panjang --target . Penggunaannya adalah:

mv -t target file1 file2 ...

find Anda perintah menjadi:

find . -type f -iname '*.cpp' -exec mv -t ./test/ {} \+

Dari halaman manual:

-exec perintah;

Jalankan perintah; benar jika 0 status dikembalikan. Semua argumen berikut untuk menemukan dianggap sebagai argumen untuk perintah sampai argumen yang terdiri dari `;' dihadapi. String `{}' diganti dengan nama file saat ini yang sedang diproses di mana pun ia muncul dalam argumen perintah, bukan hanya dalam argumen yang sendirian, seperti dalam beberapa versi find. Kedua konstruksi ini mungkin perlu di-escape (dengan `\') atau dikutip untuk melindunginya dari perluasan oleh shell. Lihat bagian CONTOH untuk contoh penggunaan opsi -exec. Perintah yang ditentukan dijalankan sekali untuk setiap file yang cocok. Perintah dijalankan di direktori awal. Ada masalah keamanan yang tidak dapat dihindari seputar penggunaan tindakan -exec; Anda sebaiknya menggunakan opsi -execdir sebagai gantinya.

-exec perintah {} +

Varian dari tindakan -exec ini menjalankan perintah yang ditentukan pada file yang dipilih, tetapi baris perintah dibuat dengan menambahkan setiap nama file yang dipilih di bagian akhir; jumlah total pemanggilan perintah akan jauh lebih sedikit daripada jumlah file yang cocok. Baris perintah dibangun dengan cara yang hampir sama dengan xargs membangun baris perintahnya. Hanya satu instance dari `{}' yang diperbolehkan dalam perintah. Perintah dijalankan di direktori awal.


Persamaan standar dari find -iname ... -exec mv -t dest {} + untuk find implementasi yang tidak mendukung -iname atau mv implementasi yang tidak mendukung -t adalah menggunakan shell untuk mengurutkan ulang argumen:

find . -name '*.[cC][pP][pP]' -type f -exec sh -c '
  exec mv "[email protected]" /dest/dir/' sh {} +

Dengan menggunakan -name '*.[cC][pP][pP]' , kami juga menghindari ketergantungan pada lokal saat ini untuk memutuskan apa versi huruf besar dari c atau p .

Perhatikan bahwa + , bertentangan dengan ; tidak istimewa di shell mana pun sehingga tidak perlu dikutip (walaupun mengutip tidak akan merugikan, kecuali tentu saja dengan shell seperti rc yang tidak mendukung \ sebagai operator pengutipan).

/ di belakangnya di /dest/dir/ sehingga mv gagal dengan kesalahan alih-alih mengganti nama foo.cpp ke /dest/dir jika hanya satu cpp file ditemukan dan /dest/dir tidak ada atau bukan direktori (atau symlink ke direktori).


Linux
  1. Mengapa /bin/sh Menunjuk Ke /bin/dash Dan Bukan /bin/bash??

  2. “tidak dapat Membuat Direktori Cache /home//.composer/cache/repo/https—packagist.org/, Atau Direktori Tidak Dapat Ditulis. Melanjutkan Tanpa Cache”?

  3. Mengapa regex ini tidak berfungsi di linux?

  1. Mengapa meletakkan hal-hal selain /home ke partisi terpisah?

  2. gema atau cetak /dev/stdin /dev/stdout /dev/stderr

  3. Mengapa direktori /home, /usr, /var, dll. Semuanya memiliki nomor inode yang sama (2)?

  1. Linux:Perbedaan Antara /dev/console , /dev/tty Dan /dev/tty0?

  2. Mengapa `keluar &` Tidak Berfungsi?

  3. Mengapa < atau > diperlukan untuk menggunakan /dev/tcp