Bagaimana saya bisa menangani spasi dalam nama file saat menggunakan xargs pada hasil pencarian?

28

Salah satu praktik umum saya adalah melakukan greps pada semua file dari jenis tertentu, misalnya, menemukan semua file HTML yang memiliki kata "rumpus" di dalamnya. Untuk melakukannya, saya gunakan

find /path/to -name "*.html" | xargs grep -l "rumpus"

Terkadang, findakan mengembalikan file dengan spasi dalam namanya seperti my new file.html. Namun, ketika xargsmeneruskan ini grep, saya mendapatkan kesalahan ini:

grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory

Saya bisa melihat apa yang terjadi di sini: baik pipa atau xargsmemperlakukan ruang sebagai pembatas antara file. Namun, untuk kehidupan saya, saya tidak tahu bagaimana cara mencegah perilaku ini. Bisakah itu dilakukan dengan find+ xargs? Atau apakah saya harus menggunakan perintah yang sama sekali berbeda?

kasar
sumber

Jawaban:

29

Menggunakan

find ... -print0 | xargs -0 ...

misalnya

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"

dari halaman manual find

-print0
          True; print the full file name on the standard  output,  followed
          by  a  null  character  (instead  of  the  newline character that
          ‘-print’ uses).  This allows file names that contain newlines  or
          other  types  of  white space to be correctly interpreted by pro-
          grams that process the find output.  This option  corresponds  to
          the ‘-0’ option of xargs.
user9517 mendukung GoFundMonica
sumber
15

Anda tidak perlu menggunakan xargs , karena find dapat menjalankan perintah itu sendiri. Saat melakukan ini, Anda tidak perlu khawatir tentang shell menafsirkan karakter dalam nama.

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +

dari halaman manual find

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

sciurus
sumber
Saya akan memperbaiki ini tetapi saya belum pergi hari ini - saya akan melakukannya besok.
user9517 mendukung GoFundMonica
1
@ Iain - ini dia (saya setuju, ngomong-ngomong).
Eduardo Ivanec
Hanya dengan menggunakan Anda masih ketinggalan fitur xargs, ditambah Anda harus berurusan dengan aturan mengutip konyol. Lihat argumen -P ke xargs jika Anda memiliki lebih dari satu core / CPU.
Slartibartfast
8

Jika versi find dan xarg pada sistem Anda tidak mendukung -print0dan -0beralih (misalnya pencarian dan xarg AIX), Anda dapat menggunakan ini:

find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"

Di sini sed akan mengurus pelarian ruang untuk xargs.

Jan Ptáčník
sumber
Ini membantu saya karena saya memiliki daftar panjang nama file yang sulit untuk diproduksi yang saya gunakan beberapa kali. Saya tidak bisa pergi findsemuanya lagi.
Scott M.