GNU/Linux >> Belajar Linux >  >> Linux

Cara meneruskan output perintah sebagai beberapa argumen ke perintah lain

Untuk kelengkapan, saya juga akan menyebutkan substitusi perintah dan menjelaskan mengapa ini tidak disarankan:

cp $(grep -l "pattern" input) directory/

(Sintaks backtick cp `grep -l "pattern" input` directory/ kira-kira setara, tetapi sudah usang dan berat; jangan gunakan itu.)

Ini akan gagal jika output dari grep menghasilkan nama file yang berisi spasi putih atau karakter meta shell.

Tentu saja, tidak apa-apa menggunakan ini jika Anda tahu persis file mana yang menamai grep dapat menghasilkan, dan telah memverifikasi bahwa tidak ada yang bermasalah. Namun untuk skrip produksi, jangan gunakan ini.

Bagaimanapun, untuk skenario OP, di mana Anda perlu merujuk ke setiap kecocokan satu per satu dan menambahkan ekstensi ke dalamnya, xargs atau while read alternatif lebih unggul.

Dalam kasus terburuk (artinya nama file bermasalah atau tidak ditentukan), teruskan kecocokan ke subkulit melalui xargs :

grep -l "pattern" input |
xargs -r sh -c 'for f; do cp "$f" "$f.bac"; done' _

... di mana jelas skrip di dalam for loop bisa menjadi rumit secara sewenang-wenang.

Dalam kasus yang ideal, perintah yang ingin Anda jalankan cukup sederhana (atau serbaguna) sehingga Anda dapat dengan mudah memberikannya daftar nama file yang panjang dan sewenang-wenang. Misalnya, GNU cp memiliki -t opsi untuk memfasilitasi penggunaan xargs ini (-t pilihan memungkinkan Anda untuk menempatkan direktori tujuan pertama pada baris perintah, sehingga Anda dapat meletakkan file sebanyak yang Anda suka di akhir perintah):

grep -l "pattern" input | xargs cp -t destdir

yang akan berkembang menjadi

cp -t destdir file1 file2 file3 file4 ...

untuk kecocokan sebanyak xargs dapat masuk ke baris perintah cp , diulang sebanyak yang diperlukan untuk meneruskan semua file ke cp . (Sayangnya, ini tidak cocok dengan skenario OP; jika Anda perlu mengganti nama setiap file saat menyalin, Anda hanya perlu memasukkan dua argumen per cp pemanggilan:nama file sumber dan nama file tujuan untuk menyalinnya.)

Jadi dengan kata lain, jika Anda menggunakan sintaks substitusi perintah dan grep menghasilkan benar-benar daftar panjang kecocokan, Anda berisiko menabrak ARG_MAX dan kesalahan "Daftar argumen terlalu panjang"; tapi xargs akan secara khusus menghindari ini dengan hanya menyalin argumen sebanyak yang dapat diteruskan dengan aman ke cp sekaligus, dan menjalankan cp beberapa kali jika perlu.


Anda dapat menggunakan xargs :

grep 'pattern' input | xargs -I% cp "%" "%.bac"

Anda dapat menggunakan $() untuk menginterpolasi output dari perintah. Jadi, Anda bisa menggunakan kill -9 $(grep -hP '^\d+$' $(ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }')) jika Anda mau.


Selain jawaban bagus Chris Jester-Young, saya akan mengatakan bahwa xargs juga merupakan solusi yang baik untuk situasi ini:

grep ... `ls -lad ... | awk '{ print $9 }'` | xargs kill -9

akan berhasil. Semua bersama-sama:

grep -hP '^\d+$' `ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }'` | xargs kill -9

Linux
  1. Bagaimana Cara Melewati Parameter Ke Alias?

  2. Bagaimana Melewati Output Dari Satu Perintah Sebagai Argumen ke Yang Lain?

  3. Bagaimana Menemukan Banyak String Dalam File??

  1. Cara memahami keluaran warna

  2. Bagaimana cara menambahkan output ke file?

  3. Bagaimana cara menggabungkan beberapa baris keluaran menjadi satu baris?

  1. Bagaimana saya bisa mengulang output dari perintah shell?

  2. Bagaimana cara meneruskan argumen ke skrip yang dipanggil oleh perintah sumber?

  3. Cara grep keluaran ps dengan header