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.