Kesim kullanarak ayırıcı için daha fazla alan nasıl belirlenir?


196

Cut komutuyla daha fazla alan için alan sınırlayıcısı belirtmenin bir yolu var mı? ("" + gibi)? Örneğin: Aşağıdaki dizede '3744' değerine ulaşmayı seviyorum, hangi alan sınırlayıcısını söylemeliyim?

$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' 'istediğim şey değil, çünkü bu sadece tek bir alan için. awkBen de aradığım şey değil, ama 'kesim' ile nasıl yapılır?

Teşekkürler.


13
en iyi cevap trburada gösterildiği gibi kullanıyor : stackoverflow.com/a/4483833/168143
John Bachir

1
Sorulan asıl soru ile doğrudan ilgili değil, ps+ modern yerine çoğu modern dağıtımda mevcut olanı grepkullanabilirsiniz pgrep. Sonucu tam olarak ihtiyacınız olan formda döndürür.
ccpizza

Yanıtlar:


323

Aslında awkise tam size bakarak gerektiğini aracı:

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

ya da düzenli ifadeleri bildiğinden greptamamen ayrılabilirsiniz awk:

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

Bazı tuhaf bir nedenden dolayı, gerçekten, Ama olamaz kullanmak awk, çöküşün ilk tek alana tümüyle beyaz gibi yapabileceğiniz diğer daha basit şeyler vardır:

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

Bu grephile, bu arada, sadece jbosssüreçleri almak için değil grep jboss, awkvaryantı için de düzgün bir yoldur ( varyant için de aynen ).

grepSüreç bir hazır olacak grep [j]bossböylece onun süreç komuta tarafından yakalanmış olmayacak grepkarakter sınıfı arıyor şekilde kendine [j]izledi boss.

Bu, | grep xyz | grep -v grepbazı insanların kullandığı paradigmadan kaçınmanın şık bir yoludur .


1
Mükemmel cevap. Bir daha ihtiyacım olduğunda tekrar bakmak için geri geleceğim.
Mart'ta eğlence

grepHüner crontab dosyalarındaki değil işin görünüyor. Herhangi bir nedenle?
Amir Ali Akbari

2
Grep hilesini öğrenmeye ve unutmaya devam ediyorum. En son hatırlatmam için teşekkürler. Belki bu sefer yapışacaktır. Ama bahse girmezdim.
Michael Burr

@Michael, bu ipucunu (ve muhtemelen başkalarını) ayda bir kez size postayla göndermek için bir yere bir cron işi kurmalısınız :-)
paxdiablo

3
Oliver, bazen "X ile Y'yi nasıl yaparım?" "Y kullanmayın, onun yerine Z kullanın". OP bu yanıtı kabul ettiğinden, muhtemelen onları ikna ettim :-)
paxdiablo

113

awksürümü muhtemelen gitmek için en iyi yoldur, ancak cutilk önce tekrarları sıkarsanız da kullanabilirsiniz 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
Süslü illüstrasyon.
Haggra

tr -s ' 'çok güzel! Umarım bunu daha iyi hatırlayabilirimawk
Chris

@Chris İtiraz etmeliyim: D Awk bu şeyler için çok daha iyi !!
fedorqui 'SO

41

Bunun için tr -s komutunu kullanmayı seviyorum

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

Bu, 1 boşluktaki tüm beyaz boşlukları sıkar. Bu şekilde kesime boşluk ayırıcı olarak kullanılmasını söylemek beklendiği gibi onurlandırılır.


1
Bunun cevap olması gerektiğini düşünüyorum, OP isteğine daha yakın (kesim kullanması istendi). Bu yaklaşım, awk yaklaşımından% 5-10 daha yavaştır (çünkü tr ile başa çıkmak için bir boru daha vardır), ancak genel olarak bu önemsiz olacaktır.
Oliver

11

tr -s [:blank:]En iyi cevap olarak aday göstereceğim .

Neden kesim kullanmak istiyoruz? "Üçüncü alanı ve sonraki her alanı istiyoruz, ilk iki alanı atlayarak" sihirli komutuna sahip.

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

Kaç tane alan olacağını bilmediğimiz awk veya perl split için eşdeğer bir komut olduğuna inanmıyorum, yani 3. alanı X alanından koyuyoruz.


9

Daha kısa / daha basit çözüm: kullanım cuts(yazdığım steroidleri kesin)

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

Not o cuts5 alan 4 olarak belirtilir böylece saha dizinleri sıfır dayanır

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

Ve daha da kısa (hiç kesim kullanmamak):

pgrep jboss

8

Bunun bir yolu gitmek:

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

birbirini izleyen birden çok boşluğu tek bir boşlukla değiştirmek için.


Garip, bu OS X üzerinde çalışmaz. Sed komutu birden çok alanı bir boşluğa değiştirmez.
rjurney

2
\sbir GNU sed uzantısıdır. OS X'te sen geçebilir -Eardından, genişletilmiş düzenli ifadeler etkinleştirmek kullanmak sed bayrağı [[:space:]]yerine \s: aynen böylesed -E 's/[[:space:]]+/ /g'
Jared Ng

4

Şahsen, böyle işler için awk kullanma eğilimindeyim. Örneğin:

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

6
Bu sıkıştırılabilir ps axu | awk '/[j]boss/ {print $5}'.
zwol

1
Awk daha yavaş değil (özellikle gereksiz başka işlemler olduğunda), sonra sed / grep / cut?
pihentagy

2

Alternatif olarak, her zaman perl vardır:

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

Veya, # 3 alanından başlayarak tüm alanları almak istiyorsanız (yukarıdaki cevaplardan birinde belirtildiği gibi):

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

Bu lsofdenedim çıktı ile çalışmaz lsof|perl -lane 'print $F[5]'Bu bazen 5. sütun, bazen 6. alır
rubo77

Bence soru, değişen sayıda boşluk içerebilecek sınırlayıcıların nasıl kullanılacağıydı. Bu amaçla cevap doğruydu.
21'de flitz

Sorun, sütun sayısının her satırda her zaman tutarlı olmamasıdır.
21'de flitz


2

Bir ps çıkışından sütun seçmek istiyorsanız, -o kullanmamak için herhangi bir neden var mı?

Örneğin

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

Minimum sütun genişliği tahsis edildi, dolgu yok, sadece tek boşluk alan ayırıcısı.

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 ve vsz değerleri 10 karakter genişliğinde, 1 boşluk alanı ayırıcısı ile verilmiştir.

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

Bir komut dosyasında kullanılır: -

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

0

Cut komutunu kullanmanız gerekiyorsa başka bir yol

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

Solaris'te awk'yi nawkveya ile değiştirin/usr/xpg4/bin/awk


0

Perl'in boşluklu alanları işleme şeklini hala seviyorum.
İlk alan $ F [0].

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

0

Benim yaklaşım PID / tmp bir dosyaya depolamak ve -Sseçeneğini kullanarak doğru işlemi bulmaktır ssh. Bu bir yanlış kullanım olabilir ama benim için işe yarıyor.

#!/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

Daha iyi bir yaklaşım SSH_PID, dosya eski olabileceğinden ve yanlış bir işlemi öldürebileceğinden, onu öldürmeden önce hakkı sorgulamak olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.