GNU/Linux >> Belajar Linux >  >> Linux

Pisahkan keluaran perintah dengan kolom menggunakan Bash?

Salah satu cara mudah adalah dengan menambahkan kode tr untuk memeras pemisah bidang berulang:

$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4

Harap dicatat bahwa tr -s ' ' opsi tidak akan menghapus satu pun spasi terdepan. Jika kolom Anda rata kanan (seperti ps pid)...

$ ps h -o pid,user -C ssh,sshd | tr -s " "
 1543 root
19645 root
19731 root

Kemudian pemotongan akan menghasilkan baris kosong untuk beberapa bidang tersebut jika itu adalah kolom pertama:

$ <previous command> | cut -d ' ' -f1

19645
19731

Kecuali jika Anda mengawalinya dengan spasi, tentu saja

$ <command> | sed -e "s/.*/ &/" | tr -s " "

Sekarang, untuk kasus nomor pid ini (bukan nama), ada fungsi yang disebut pgrep :

$ pgrep ssh


Fungsi cangkang

Namun, secara umum sebenarnya masih memungkinkan untuk menggunakan fungsi shell secara ringkas, karena ada hal yang rapi tentang read perintah:

$ <command> | while read a b; do echo $a; done

Parameter pertama yang dibaca, a , memilih kolom pertama, dan jika ada lebih banyak, yang lainnya akan dimasukkan ke dalam b . Akibatnya, Anda tidak memerlukan variabel lebih dari jumlah kolom Anda +1 .

Jadi,

while read a b c d; do echo $c; done

kemudian akan menampilkan kolom ke-3. Seperti yang ditunjukkan dalam komentar saya...

Pembacaan yang disalurkan akan dieksekusi di lingkungan yang tidak meneruskan variabel ke skrip panggilan.

out=$(ps whatever | { read a b c d; echo $c; })

arr=($(ps whatever | { read a b c d; echo $c $b; }))
echo ${arr[1]}     # will output 'b'`


Solusi Larik

Jadi kami kemudian berakhir dengan jawaban oleh @frayser yang menggunakan variabel shell IFS yang defaultnya adalah spasi, untuk membagi string menjadi array. Ini hanya berfungsi di Bash. Dash dan Ash tidak mendukungnya. Saya mengalami kesulitan membagi string menjadi komponen dalam Busybox. Cukup mudah untuk mendapatkan satu komponen (misalnya menggunakan awk) dan kemudian mengulanginya untuk setiap parameter yang Anda butuhkan. Tapi kemudian Anda berulang kali memanggil awk di baris yang sama, atau berulang kali menggunakan blok baca dengan gema di baris yang sama. Yang tidak efisien atau cantik. Jadi Anda akhirnya memisahkan menggunakan ${name%% *} dan seterusnya. Membuat Anda mendambakan beberapa keterampilan Python karena sebenarnya skrip shell tidak lagi menyenangkan jika setengah atau lebih dari fitur yang biasa Anda gunakan, hilang. Tetapi Anda dapat berasumsi bahwa bahkan python tidak akan diinstal pada sistem seperti itu, dan ternyata tidak;-).


Menurut saya cara paling sederhana adalah dengan menggunakan awk . Contoh:

$ echo "11383 pts/1    00:00:00 bash" | awk '{ print $4; }'
bash

Linux
  1. perintah ekspor bash

  2. Mengarahkan output perintah ke variabel di bash gagal

  3. Redirect semua output ke file menggunakan Bash di Linux?

  1. Menggunakan Perintah Nama Dasar Linux di Skrip Bash

  2. Redirect output dari perintah waktu di unix ke dalam variabel di bash?

  3. Bash find perintah output verbose

  1. Cara membagi iso atau file menggunakan perintah 'split' di Linux

  2. Menggunakan output dari perintah sebelumnya di bash

  3. Secara otomatis menangkap keluaran dari perintah terakhir ke dalam variabel menggunakan Bash?