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