Anda membingungkan dua jenis input yang sangat berbeda.
- Input standar (
stdin
)
- Argumen baris perintah
Ini berbeda, dan berguna untuk tujuan yang berbeda. Beberapa perintah dapat mengambil input dalam dua cara, tetapi mereka biasanya menggunakannya secara berbeda. Ambil contoh wc
perintahnya:
Lulus masukan dengan stdin
:
ls | wc -l
Ini akan menghitung garis dalam output dari ls
Melewati input dengan argumen baris perintah:
wc -l $(ls)
Ini akan menghitung baris dalam daftar file yang dicetak olehls
Hal yang sangat berbeda.
Untuk menjawab pertanyaan Anda, sepertinya Anda ingin menangkap laju dari output perintah pertama, dan kemudian menggunakan kursor sebagai argumen baris perintah untuk perintah kedua. Inilah satu cara untuk melakukan itu:
rate=$(command1 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p')
command2 -t "rate was $rate"
Penjelasan tentang sed
:
- The
s/pattern/replacement/
perintah untuk mengganti beberapa pola
- Polanya berarti: baris harus dimulai dengan "rate" (
^rate
) diikuti oleh dua karakter ( ..
), diikuti oleh 0 atau lebih digit, diikuti oleh %
, diikuti oleh sisa teks ( .*
)
\1
dalam penggantian berarti isi dari ekspresi pertama yang ditangkap di dalam \(...\)
, jadi dalam hal ini digit sebelum %
tanda
- The
-n
bendera sed
perintah berarti untuk tidak mencetak baris secara default. The p
di akhir s///
perintah berarti untuk mencetak garis jika ada penggantinya. Singkatnya, perintah akan mencetak sesuatu hanya jika ada kecocokan.
Untuk mensimulasikan output
command1
saya menggunakan pernyataan gema ini:Tes cepat:
Itu semua bagus, jadi mari kita uraikan:
Jadi kita mendapatkan garis yang kita inginkan
command1
, mari kita sampaikan kecommand2
:Saya berharap
"rate was "$(command1 | grep 'rate')
untuk menyatukan secara otomatis. Jika itu tidak berhasil karena spasi, Anda seharusnya dapat meneruskan input seperti itu sebagai gantinya:sumber
Coba ini menggunakan grep & pcre :
sumber
Tugas pertama adalah mengekstraksi kurs dari baris itu. Dengan GNU grep (Linux yang tidak tertanam atau Cygwin), Anda dapat menggunakan
-o
opsi ini. Bagian yang Anda inginkan adalah bagian yang hanya mengandung digit, dan diikuti oleh%
tanda. Jika Anda tidak ingin mengekstraksi%
sendiri, Anda perlu trik tambahan: pernyataan lookahead lebar nol , yang tidak cocok dengan apa pun kecuali hanya jika tidak ada yang diikuti%
.Kemungkinan lain adalah menggunakan sed. Untuk mengekstrak bagian dari baris dalam sed, gunakan
s
perintah, dengan regex yang cocok dengan seluruh baris (dimulai dengan^
dan diakhiri dengan$
), dengan bagian untuk mempertahankan dalam grup (\(…\)
). Ganti seluruh baris dengan konten grup yang ingin dipertahankan. Secara umum, berikan-n
opsi untuk mematikan pencetakan default dan letakkanp
pengubah untuk mencetak garis di mana ada sesuatu untuk diekstraksi (di sini ada satu baris sehingga tidak masalah). Lihat Mengembalikan hanya sebagian dari garis setelah pola yang cocok dan Mengekstrak regex yang cocok dengan 'sed' tanpa mencetak karakter di sekitarnya untuk trik sed yang lebih banyak.Lebih fleksibel lagi daripada sed, awk. Awk menjalankan instruksi untuk setiap baris dalam bahasa imperatif kecil. Ada banyak cara untuk mengekstraksi kurs di sini; Saya memilih bidang kedua (bidang dibatasi oleh spasi putih secara default), dan menghapus semua karakter di dalamnya yang bukan angka.
Langkah selanjutnya, sekarang setelah Anda mengekstraksi kurs, adalah meneruskannya sebagai argumen
command2
. Alat untuk itu adalah susbtitusi perintah . Jika Anda memasukkan perintah ke dalam$(…)
(dolar-kurung), hasilnya diganti ke baris perintah. Output dari perintah dibagi menjadi kata-kata yang terpisah di setiap blok spasi, dan setiap kata diperlakukan sebagai pola wildcard; kecuali jika Anda ingin ini terjadi, menempatkan tanda kutip ganda sekitar substitusi perintah:"$(…)"
. Dengan tanda kutip ganda, output dari perintah digunakan secara langsung sebagai parameter tunggal (satu-satunya transformasi adalah bahwa baris baru di akhir output dihapus).sumber
Anda dapat menggunakan
grep
dan itu PCRE - Ekspresi Reguler Kompatibel Kompatibel. Ini memungkinkan Anda untuk menggunakan tampilan di belakang untuk mencocokkan nilai laju, tanpa menyertakan "nilai" string dalam hasil Anda saat mengambilnya.Contoh
Detail
Di atas
grep
berfungsi sebagai berikut:-o
hanya akan mengembalikan apa yang kita cari\d+
, yang merupakan digit di dalam parens.-P
mengaktifkan fitur PCRE grep(?<=^rate \()
hanya akan mengembalikan string yang dimulai dengan "rate ("perintah2
Untuk menangkap nilai "rate" Anda dapat menjalankan
command1
seperti:Kemudian untuk perintah 2 Anda, Anda cukup menggunakan variabel itu.
Anda bisa menjadi mewah dan membuat itu semua menjadi satu baris:
Ini akan mengeksekusi command1 di dalam
$(..)
blok eksekusi, mengambil hasilnya dan memasukkannya ke dalam-t=..
saklar command2 .sumber
Saya biasanya menggunakan `command` untuk menempatkan output sebagai argumen ke perintah lain. Misalnya, untuk menemukan sumber daya yang dikonsumsi oleh proses foo di freebsd adalah:
Di sini, pgrep digunakan untuk mengekstrak PID dari proses foo yang dilewatkan ke perintah procstat yang mengharapkan PID proses sebagai argumen.
sumber