Perintah pemipaan setelah xarg yang di-pipe

38

HP-UX ***** B.11.23 U ia64 **** lisensi pengguna tidak terbatas

find . -type d -name *log* | xargs ls -la

memberi saya nama direktori (yang berisi lognama direktori) diikuti oleh semua file dalam direktori itu.

Direktori  /var/opt/SID/application_a/log/,  /var/opt/SID/application_b/log/,  /var/opt/SID/application_c/log/dan sebagainya berisi file-file log.

Saya ingin hanya dua file log terbaru yang didaftar oleh lsperintah, yang biasanya saya temukan menggunakan ls -latr | tail -2.

Outputnya harus seperti ini ..

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2tidak memberi saya hasil di atas. Yang saya dapatkan adalah daftar dua file find . -type d -name *log* | xargs ls -laperintah terakhir.

Jadi bisakah saya memipakan perintah setelah dipipet xargs? Bagaimana lagi saya meminta, untuk mendapatkan daftar file yang dihasilkan dalam format di atas?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

memberi saya daftar nama direktori sepuluh di dalam direktori saat ini yang kebetulan /var/opt/SIDdan itu juga bukan yang saya inginkan.

orang lain1
sumber
2
Anda harus mengutip *log*jika tidak, shell akan mengembangkannya.
Anthon
Sadarilah bahwa sh -cmengharapkan nama perintah (parameter 0) sebagai argumen kedua, jadi Anda harus selalu melakukannya find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail(perhatikan lstailpada bagian akhir, yang akan berfungsi seperti $0untuk shell yang dibuat). Kalau tidak, hasil pertama Anda akan mengisi peran itu dan tidak digunakan.
Jonas

Jawaban:

58

Anda hampir sampai. Dalam perintah terakhir Anda, Anda dapat menggunakannya -Iuntuk melakukan yang lsbenar

-I replace-str

    Ganti kemunculan pengganti-str dalam argumen-awal dengan nama yang dibaca dari input standar. Juga, blanko tanda kutip tidak menghentikan item input; sebaliknya pemisah adalah karakter baris baru. Tersirat -xdan -L 1.

Jadi, dengan

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

Anda akan echodir ditemukan oleh find, kemudian lakukan ls | taildi atasnya.

fredtantini
sumber
temukan. -type d -name " log " | xargs -I {} sh -c "echo {}; ls -ltr {} | grep -E \" file_in | file_out \ "| tail -5" Saya menggunakan yang ini.
lain1
3
Saya lakukan denganxargs -n 1 sh -c 'echo $0'
Ginhing
1
pada macOS penggantian tidak bekerja dalam perintah yang dikutip, jadi echo $0sangat membantu (dan lebih dimengerti)
mpuncel
1
Untuk membuatnya bekerja dengan nama file dengan spasi, gunakan -print0, xargs -0dan melarikan diri {}ke tanda kutip ganda di dalam shperintah:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
Benedikt Köppel
Saya menggunakan gema "xargs -n 1 sh -c" \ $ 0 | $ func "` jika saya perlu menggunakan variabel $ func
god
5

GNU Parallel memudahkan tugas semacam ini:

find . -type d -name "*log*" | parallel --tag "ls -la {} | tail -2"

Jika Anda tidak ingin menginstal GNU Parallel sepenuhnya, Anda dapat melakukan instalasi minimal: http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Ole Tange
sumber
2

Hanya sebagai tambahan fredtantini dan sebagai klarifikasi umum (karena dokumennya agak membingungkan):

The xargs -I {}akan mengambil '{}' karakter dari input standar dan menggantinya dengan apa pun yang datang di dari pipa. Ini berarti Anda dapat benar-benar mengganti {}dengan kombinasi karakter apa saja (mungkin untuk menyesuaikan selera pemrograman pilihan Anda dengan lebih baik). Sebagai contoh : xargs -I % sh -c "echo %". Jika Anda selalu menggunakan, xargs -I {}Anda bisa menggantinya xargs -ikarena itu adalah singkatan.

The sh -cakan memberitahu pesta Anda / shell untuk membaca perintah berikutnya dari string dan bukan dari standard input. Jadi menulis sh -c "echo something"setara dengan echo something.

The xargs -I {} sh -c "echo {}"akan membaca masukan Anda buat dengan sh -cyang echo {}. Karena Anda mengatakannya untuk mengganti {}dengan argumen yang Anda dapatkan dari pipa, itulah yang akan terjadi.

Anda dapat dengan mudah menguji ini bahkan tanpa pemipaan, cukup ketikkan perintah di atas dalam terminal. Apa pun yang Anda tulis selanjutnya akan dikeluarkan ke terminal (Ctrl-D untuk keluar).

Dalam ls -la {}perintah itu hal yang sama terjadi lagi. The {}diganti dengan isi perintah pra-pipa.

Borisu
sumber