$ ls *mp3 | xargs mplayer
Playing Lemon.
File not found: 'Lemon'
Playing Tree.mp3.
File not found: 'Tree.mp3'
Exiting... (End of file)
Perintah saya gagal karena file "Lemon Tree.mp3" berisi spasi dan xargs menganggapnya dua file. Dapatkah saya membuat + xargs berfungsi dengan nama file seperti ini?
ls |grep mp3 |sed -n "7p"
Anda hanya bisa menggunakanecho "Lemon Tree.mp3"
.Jawaban:
The
xargs
perintah mengambil karakter putih ruang (tab, spasi, baris baru) sebagai pembatas. Anda dapat mempersempitnya hanya untuk karakter baris baru ('\ n') dengan-d
opsi seperti ini:Ini hanya berfungsi dengan GNU xargs. Untuk sistem BSD, gunakan
-0
opsi seperti ini:Metode ini lebih sederhana dan juga berfungsi dengan GNU xargs.
sumber
-E
, mis:xargs -E '\n'
Utilitas xargs membaca string yang dibatasi spasi, tab, baris baru dan akhir file dari input standar dan menjalankan utilitas dengan string sebagai argumen.
Anda ingin menghindari menggunakan ruang sebagai pembatas. Ini dapat dilakukan dengan mengubah pembatas untuk xargs. Menurut manual:
Seperti:
Untuk menjawab pertanyaan tentang memainkan mp3 ketujuh; lebih mudah dijalankan
sumber
find
dan GNUxargs
; tidak semua versi dari program-program tersebut mendukung opsi-opsi tersebut (walaupun ada kasus yang harus dibuat).find
dengan-print0
danxargs
dengan-0
. Namun, AFAIK, HP-UX, AIX, dan Solaris tidak (tapi saya harus diperbaiki: HP-UX 11i tidak; Solaris 10 tidak; AIX 5.x tidak; tetapi mereka bukan versi saat ini ). Tidak akan sulit untuk mengubahsed
, misalnya, untuk menggunakan 'baris' yang berakhir dengan'\0'
alih - alih'\n'
, dan POSIX 2008getdelim()
akan membuatnya mudah untuk dikelola.Mencoba
dari pada
sumber
xargs pada MacOS tidak memiliki opsi -d, jadi solusi ini menggunakan -0 sebagai gantinya.
Dapatkan ls untuk mengeluarkan satu file per baris, lalu terjemahkan baris baru ke dalam nol dan beri tahu xargs untuk menggunakan nol sebagai pembatas:
ls -1 *mp3 | tr "\n" "\0" | xargs -0 mplayer
sumber
Ini membantu dalam kasus saya untuk menghapus file yang berbeda dengan spasi. Itu harus bekerja juga dengan mplayer. Trik yang diperlukan adalah tanda kutip. (Diuji pada Linux Xubuntu 14.04.)
sumber
Jawaban Dick.Guertin [1] menyatakan bahwa seseorang dapat melarikan diri dari spasi dalam nama file adalah alternatif berharga untuk solusi lain yang disarankan di sini (seperti menggunakan karakter nol sebagai pemisah daripada spasi putih). Tapi itu bisa lebih sederhana - Anda tidak benar-benar membutuhkan karakter yang unik. Anda bisa menambahkan sedan ruang yang hilang secara langsung:
Selain itu, grep hanya diperlukan jika Anda hanya ingin file dengan spasi di namanya. Lebih umum (misalnya, ketika memproses batch file beberapa di antaranya memiliki spasi, beberapa tidak), lewati saja grep:
Kemudian, tentu saja, nama file mungkin memiliki spasi putih selain kosong (misalnya, tab):
Itu mengasumsikan Anda memiliki sed yang mendukung -r (extended regex) seperti GNU sed atau versi terbaru dari bsd sed (misalnya, FreeBSD yang awalnya mengeja opsi "-E" sebelum FreeBSD 8 dan mendukung -r & -E untuk kompatibilitas setidaknya melalui FreeBSD 11). Jika tidak, Anda dapat menggunakan ekspresi braket kelas regex karakter dasar dan secara manual memasukkan spasi dan karakter tab di
[]
pembatas.[1] Ini mungkin lebih tepat sebagai komentar atau edit untuk jawaban itu, tetapi saat ini saya tidak memiliki reputasi yang cukup untuk berkomentar dan hanya dapat menyarankan suntingan. Karena bentuk terakhir di atas (tanpa grep) mengubah perilaku jawaban asli Dick. Guertin, pengeditan langsung mungkin tidak tepat.
sumber
ls | grep mp3 | sed -n "7p" | xargs -i mplayer {}
Perhatikan bahwa dalam perintah di atas,
xargs
akan memanggilmplayer
lagi untuk setiap file. Ini mungkin tidak diinginkan untukmplayer
, tetapi mungkin oke untuk target lain.sumber
mplayer
disebut baru untuk setiap file. Itu penting jika Anda mencoba misalnya... | xargs -I{} mplayer -shuffle {}
: ini akan bermain dalam urutan yang sepenuhnya deterministik-shuffle
.xargs
sebagian besar digunakan dengan perintah yang menerima daftar nama file (contoh mudah:)rm
, dan mencoba untuk mengirimkan nama file sebanyak yang dapat masuk ke setiap doa, hanya membelah menjadi beberapa doa jika diperlukan. Anda dapat melihat perbedaan ketika Anda menggunakan perintah di mana setiap doa terlihat, sepertiecho
(default):seq 0 100000 | xargs
mencetak semua angka dari 0 hingga 23695 (khusus platform, tetapi itulah yang terjadi pada sistem saya) pada baris pertama, ke 45539 pada saluran 2, dll. Dan Anda benar, untuk sebagian besar perintah, itu tidak masalah.Pada macOS 10.12.x (Sierra), jika Anda memiliki spasi dalam nama file atau subdirektori, Anda dapat menggunakan yang berikut ini:
sumber
Itu tergantung pada (a) seberapa terlampir Anda ke nomor 7 yang bertentangan dengan, katakanlah, Lemon, dan (b) apakah ada nama file Anda yang berisi baris baru (dan apakah Anda bersedia untuk mengganti nama mereka jika mereka melakukannya).
Ada banyak cara untuk menghadapinya, tetapi beberapa di antaranya adalah:
The
read
loop tidak bekerja jika nama file mengandung baris; yang lain bekerja dengan benar bahkan dengan baris baru di namanya (apalagi spasi). Untuk uang saya, jika Anda memiliki nama file yang mengandung baris baru, Anda harus mengganti nama file tanpa baris baru. Menggunakan tanda kutip ganda di sekitar nama file adalah kunci untuk loop bekerja dengan benar.Jika Anda memiliki GNU
find
dan GNUxargs
(atau FreeBSD (* BSD?), Atau Mac OS X), Anda juga dapat menggunakan opsi-print0
dan-0
, seperti pada:Ini berfungsi terlepas dari isi nama (hanya dua karakter yang tidak dapat muncul dalam nama file adalah slash dan NUL, dan slash tidak menyebabkan masalah dalam jalur file, jadi menggunakan NUL sebagai pembatas nama mencakup semuanya). Namun, jika Anda perlu menyaring 6 entri pertama, Anda memerlukan program yang menangani 'baris' yang diakhiri dengan NUL alih-alih baris baru ... dan saya tidak yakin ada.
Yang pertama adalah yang paling sederhana untuk kasus spesifik yang ada; namun, itu mungkin tidak menggeneralisasi untuk menutupi skenario Anda yang belum Anda daftarkan.
sumber
Aku tahu bahwa aku tidak menjawab
xargs
pertanyaan secara langsung , tapi itu layak disebutfind
's-exec
pilihan.Diberikan sistem file berikut:
Perintah find dapat dibuat untuk menangani ruang di Dream Theater dan King's X. Jadi, untuk menemukan drummer dari setiap band menggunakan grep:
Dalam
-exec
opsi{}
singkatan nama file termasuk jalur. Perhatikan bahwa Anda tidak perlu menghindarinya atau menuliskannya dalam tanda kutip.Perbedaan antara
-exec
terminator (+
dan\;
) adalah+
mengelompokkan sebanyak mungkin nama file ke satu baris perintah. Sedangkan\;
akan menjalankan perintah untuk setiap nama file.Jadi,
find bands/ -type f -exec grep Drums {} +
akan menghasilkan:dan
find bands/ -type f -exec grep Drums {} \;
akan menghasilkan:Dalam hal
grep
ini memiliki efek samping baik mencetak nama file atau tidak.Tentu saja,
grep
opsi-h
dan-H
akan mengontrol apakah nama file dicetak terlepas dari bagaimanagrep
dipanggil.xargs
xargs
juga dapat mengontrol bagaimana file manusia berada di baris perintah.xargs
secara default mengelompokkan semua argumen ke dalam satu baris. Untuk melakukan hal yang sama yang-exec \;
digunakanxargs -l
. Perhatikan bahwa-t
opsi memberi tahuxargs
untuk mencetak perintah sebelum menjalankannya.Lihat bahwa
-l
opsi memberi tahu xargs untuk menjalankan grep untuk setiap nama file.Lawan default (yaitu tidak ada
-l
opsi):xargs
memiliki kontrol yang lebih baik pada berapa banyak file yang dapat berada di baris perintah. Berikan-l
opsi jumlah maksimal file per perintah.Lihat yang
grep
dieksekusi dengan dua nama file karena-l2
.sumber
Diberikan judul spesifik dari posting ini, inilah saran saya:
Idenya adalah untuk mengonversi blank menjadi karakter unik apa pun, seperti '<', dan kemudian mengubahnya menjadi '\', garis miring terbalik diikuti oleh tanda kosong. Anda kemudian dapat mengirimkannya ke perintah apa pun yang Anda suka, seperti:
Kuncinya di sini terletak pada perintah 'tr' dan 'sed'; dan Anda dapat menggunakan karakter apa pun selain '<', seperti '?' atau bahkan karakter tab.
sumber
tr
? Kenapa tidak adills *.mp3 | sed -n '7!b;s/\([[:space:]]\)/\\\1/g;p'
?Solusi alternatif dapat membantu ...
Anda juga dapat menambahkan karakter nol ke akhir baris Anda menggunakan Perl, lalu gunakan
-0
opsi dalam xargs. Berbeda dengan xargs -d '\ n' (dalam jawaban yang disetujui) - ini bekerja di mana-mana, termasuk OS X.Misalnya, untuk mendaftar secara rekursif (mengeksekusi, memindahkan, dll.) File MPEG3 yang mungkin berisi spasi atau karakter lucu lainnya - Saya akan menggunakan:
(Catatan: Untuk memfilter, saya lebih suka sintaks "| grep" yang lebih mudah diingat daripada argumen "find's" --name.)
sumber