Bagaimana cara menentukan lebih banyak ruang untuk pembatas menggunakan cut?


195

Apakah ada cara untuk menentukan pembatas bidang untuk lebih banyak spasi dengan perintah cut? (seperti "" +)? Misalnya: Dalam string berikut, saya ingin mencapai nilai '3744', pembatas bidang apa yang harus saya katakan?

$ps axu | grep jboss

jboss     2574  0.0  0.0   3744  1092 ?        S    Aug17   0:00 /bin/sh /usr/java/jboss/bin/run.sh -c example.com -b 0.0.0.0

cut -d' 'bukan yang saya inginkan, karena itu hanya untuk satu ruang tunggal. awkbukan apa yang saya cari, tapi bagaimana hubungannya dengan 'cut'?

Terima kasih.


13
jawaban terbaik adalah menggunakan trseperti yang ditunjukkan di sini: stackoverflow.com/a/4483833/168143
John Bachir

1
Tidak secara langsung relevan dengan pertanyaan aktual yang diajukan tetapi alih-alih ps+ grepAnda dapat menggunakan pgrepyang tersedia di sebagian besar distro modern. Ini akan mengembalikan hasilnya persis dalam bentuk yang Anda butuhkan.
ccpizza

Jawaban:


322

Sebenarnya awkadalah persis alat Anda harus melihat ke dalam:

ps axu | grep '[j]boss' | awk '{print $5}'

atau Anda dapat membuang grepsemuanya karena awktahu tentang ekspresi reguler:

ps axu | awk '/[j]boss/ {print $5}'

Tetapi jika, untuk alasan yang aneh, Anda benar - benar tidak dapat menggunakan awk, ada hal-hal sederhana lain yang dapat Anda lakukan, seperti jatuhkan semua spasi putih ke ruang tunggal terlebih dahulu:

ps axu | grep '[j]boss' | sed 's/\s\s*/ /g' | cut -d' ' -f5

Itu greptrik, dengan cara, adalah cara yang rapi untuk hanya mendapatkan jbossproses dan bukan grep jbosssatu (ditto untuk awkvarian juga).

The grepProses akan memiliki literal grep [j]bossdalam perintah proses sehingga tidak akan tertangkap oleh grepsendiri, yang mencari kelas karakter [j]diikuti oleh boss.

Ini adalah cara yang bagus untuk menghindari | grep xyz | grep -v grepparadigma yang digunakan beberapa orang.


1
Jawaban yang bagus Saya akan datang kembali untuk mencari ini lagi lain kali saya membutuhkannya.
funroll

The greptrick tampaknya tidak bekerja di file crontab. Alasan apapun?
Amir Ali Akbari

2
Saya terus belajar dan melupakan trik grep. Terima kasih atas pengingat terakhir saya. Mungkin kali ini akan menempel. Tapi saya tidak akan bertaruh.
Michael Burr

@Michael, Anda harus mengatur pekerjaan cron di suatu tempat untuk mengirimkan tip itu (dan mungkin orang lain) kepada Anda sebulan sekali :-)
paxdiablo

3
Oliver, kadang-kadang jawaban terbaik untuk "bagaimana saya melakukan X dengan Y?" adalah "Jangan gunakan Y, gunakan Z sebagai gantinya". Karena OP menerima jawaban ini, kemungkinan saya meyakinkan mereka tentang hal itu :-)
paxdiablo

113

awkversi mungkin adalah cara terbaik untuk pergi, tetapi Anda juga dapat menggunakan cutjika Anda terlebih dahulu menekan pengulangan dengan tr:

ps axu | grep jbos[s] | tr -s ' ' | cut -d' ' -f5
#        ^^^^^^^^^^^^   ^^^^^^^^^   ^^^^^^^^^^^^^
#              |            |             |
#              |            |       get 5th field
#              |            |
#              |        squeeze spaces
#              |
#        avoid grep itself to appear in the list

10
Ilustrasi mewah.
Haggra

tr -s ' 'bagus sekali! Saya harap saya bisa mengingatnya lebih baik daripadaawk
Chris

@ Chris aku harus keberatan: D Awk jauh lebih baik untuk hal-hal ini !!
fedorqui 'SO berhenti merugikan'

41

Saya suka menggunakan perintah tr -s untuk ini

 ps aux | tr -s [:blank:] | cut -d' ' -f3

Ini meremas semua ruang putih hingga 1 ruang. Dengan cara ini, cut cut untuk menggunakan spasi sebagai pembatas dihormati seperti yang diharapkan.


1
Saya pikir ini harus menjadi jawaban, lebih dekat dengan permintaan OP (diminta untuk menggunakan cut). Pendekatan ini lebih lambat 5-10% daripada pendekatan awk (karena ada satu lagi pipa yang harus ditangani dengan tr), tetapi secara umum ini tidak akan relevan.
Oliver

11

Saya akan mencalonkan diri tr -s [:blank:]sebagai jawaban terbaik.

Mengapa kita ingin menggunakan cut? Ini memiliki perintah ajaib yang mengatakan "kami ingin bidang ketiga dan setiap bidang setelahnya, menghilangkan dua bidang pertama"

cat log | tr -s [:blank:] |cut -d' ' -f 3- 

Saya tidak percaya ada perintah setara untuk awk atau perl split di mana kita tidak tahu berapa banyak bidang yang akan ada, yaitu keluar menempatkan bidang ke-3 melalui bidang X.


9

Solusi yang lebih singkat / sederhana: gunakan cuts(kurangi steroid yang saya tulis)

ps axu | grep '[j]boss' | cuts 4

Perhatikan bahwa cutsindeks bidang berbasiskan nol sehingga bidang ke-5 ditetapkan sebagai 4

http://arielf.github.io/cuts/

Dan bahkan lebih pendek (tidak menggunakan potongan sama sekali) adalah:

pgrep jboss

8

Salah satu cara untuk mengatasinya adalah dengan:

$ps axu | grep jboss | sed 's/\s\+/ /g' | cut -d' ' -f3

untuk mengganti beberapa spasi berturut-turut dengan satu.


Aneh, ini tidak berfungsi pada OS X. Perintah sed tidak mengubah beberapa ruang menjadi satu ruang.
rjurney

2
\sadalah ekstensi sed GNU. Pada OS X Anda dapat mengedarkan -Eflag ke sed untuk mengaktifkan ekspresi reguler yang diperluas, kemudian digunakan [[:space:]]sebagai pengganti \s, seperti:sed -E 's/[[:space:]]+/ /g'
Jared Ng

4

Secara pribadi, saya cenderung menggunakan awk untuk pekerjaan seperti ini. Sebagai contoh:

ps axu| grep jboss | grep -v grep | awk '{print $5}'

6
Itu bisa dikompresi ke bawah ps axu | awk '/[j]boss/ {print $5}'.
zwol

1
Bukankah awk lebih lambat (terutama ketika ada beberapa proses lain yang berlebihan), kemudian sed / grep / cut?
pihentagy

2

Sebagai alternatif, selalu ada perl:

ps aux | perl -lane 'print $F[3]'

Atau, jika Anda ingin mendapatkan semua bidang mulai dari bidang # 3 (sebagaimana dinyatakan dalam salah satu jawaban di atas):

ps aux | perl -lane 'print @F[3 .. scalar @F]'

Ini tidak bekerja dengan output dari lsofsaya mencoba lsof|perl -lane 'print $F[5]'ini kadang-kadang mendapat kolom ke-5, kadang-kadang ke-6
rubo77

Saya pikir pertanyaannya hanyalah bagaimana menggunakan pembatas yang mungkin berisi jumlah ruang yang bervariasi. Untuk tujuan ini jawabannya benar.
Flitz

Salah satu masalahnya adalah jumlah kolom tidak selalu konsisten di setiap baris.
Flitz


2

Jika Anda ingin memilih kolom dari output ps, ada alasan untuk tidak menggunakan -o?

misalnya

ps ax -o pid,vsz
ps ax -o pid,cmd

Lebar kolom minimum dialokasikan, tanpa bantalan, hanya pemisah bidang spasi tunggal.

ps ax --no-headers -o pid:1,vsz:1,cmd

3443 24600 -bash
8419 0 [xfsalloc]
8420 0 [xfs_mru_cache]
8602 489316 /usr/sbin/apache2 -k start
12821 497240 /usr/sbin/apache2 -k start
12824 497132 /usr/sbin/apache2 -k start

Pid dan vsz diberi lebar char 10, 1 pemisah bidang spasi.

ps ax --no-headers -o pid:10,vsz:10,cmd

  3443      24600 -bash
  8419          0 [xfsalloc]
  8420          0 [xfs_mru_cache]
  8602     489316 /usr/sbin/apache2 -k start
 12821     497240 /usr/sbin/apache2 -k start
 12824     497132 /usr/sbin/apache2 -k start

Digunakan dalam skrip: -

oldpid=12824
echo "PID: ${oldpid}"
echo "Command: $(ps -ho cmd ${oldpid})"

0

Cara lain jika Anda harus menggunakan perintah cut

ps axu | grep [j]boss |awk '$1=$1'|cut -d' ' -f5

Di Solaris, ganti awk dengan nawkatau/usr/xpg4/bin/awk


0

Saya masih suka cara Perl menangani bidang dengan ruang putih.
Bidang pertama adalah $ F [0].

$ ps axu | grep dbus | perl -lane 'print $F[4]'

0

Pendekatan saya adalah menyimpan PID ke file di / tmp, dan untuk menemukan proses yang tepat menggunakan -Sopsi untuk ssh. Itu mungkin penyalahgunaan tetapi bekerja untuk saya.

#!/bin/bash

TARGET_REDIS=${1:-redis.someserver.com}
PROXY="proxy.somewhere.com"

LOCAL_PORT=${2:-6379}

if [ "$1" == "stop" ] ; then
    kill `cat /tmp/sshTunel${LOCAL_PORT}-pid`
    exit
fi

set -x

ssh -f -i ~/.ssh/aws.pem centos@$PROXY -L $LOCAL_PORT:$TARGET_REDIS:6379 -N -S /tmp/sshTunel$LOCAL_PORT  ## AWS DocService dev, DNS alias
# SSH_PID=$! ## Only works with &
SSH_PID=`ps aux | grep sshTunel${LOCAL_PORT} | grep -v grep | awk '{print $2}'`
echo $SSH_PID > /tmp/sshTunel${LOCAL_PORT}-pid

Pendekatan yang lebih baik mungkin untuk meminta SSH_PIDhak sebelum membunuhnya, karena file mungkin basi dan akan membunuh proses yang salah.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.