カットを使用して区切り文字にさらにスペースを指定するにはどうすればよいですか?


195

cutコマンドでより多くのスペースにフィールド区切り文字を指定する方法はありますか?( "" +など)?例:次の文字列で、値「3744」に到達したいのですが、どのフィールド区切り文字を言う必要がありますか?

$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' 'それは私が欲しいものではありません、それはそれが単一のスペースのためだけだからです。 awk私が探しているものでもありませんが、「カット」をどのように処理するのですか?

ありがとう。


13
ベストアンサーはtr、次のように使用します:stackoverflow.com/a/4483833/168143
John Bachir 2013年

1
ps+ 質問されている実際の質問に直接関連していませんが、+の代わりに、ほとんどの最新のディストリビューションで使用可能な質問をgrep使用できpgrepます。必要な形式で結果を正確に返します。
ccpizza 2013

回答:


322

実際にawkあるまさにあなたに探している必要がありツールは:

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

または正規表現を知ってgrepいるので、完全に捨てることができますawk

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

しかし、なんらかの奇妙な理由で実際に使用できない場合はawk、最初にすべての空白を1つのスペースに折りたたむなど、他にも簡単なことができます。

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

grepちなみに、このトリックはjbossプロセスだけを取得するgrep jbossためのawk適切な方法であり、プロセスを取得するためのものではありません(バリアントについても同じです)。

grepプロセスは、リテラルきますgrep [j]bossのでによってキャッチされることはありませんそのプロセスコマンドでgrep文字クラスを探して、それ自体は、[j]続きますboss

これは、| grep xyz | grep -v grep一部の人々が使用するパラダイムを回避するための気の利いた方法です。


1
すばらしい答えです。次回必要になったときに、これをもう一度調べるために戻ってきます。
funroll 2013年

grepトリックはcrontabファイルでは動作しないようです。何らかの理由?
Amir Ali Akbari 14

2
私はgrepトリックを学び、忘れ続けています。最近のリマインダーをありがとう。たぶん今回はこだわる。しかし、私はそれに賭けません。
マイケル・バー2017年

@Michael、あなたは月に一度そのチップ(そしておそらく他の人)にあなたにメールするためにどこかにcronジョブを設定すべきです:-)
paxdiablo

3
オリバー、「XとYをどのように組み合わせるのか」に対する最良の答えは時々あります。「Yを使用せず、代わりにZを使用する」です。OPがこの回答を受け入れたので、私はそれらを確信している可能性があります:-)
paxdiablo

113

awkバージョンがおそらく最善の方法ですが、cut最初にリピートをtr次のように圧縮する場合にも使用できます:

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

9
派手なイラスト。
Haggra 2018年

tr -s ' '素晴らしいです!私はそれよりもよく覚えていると思いますawk
Chris

@Chris私は反対しなければなりません:D Awkはこれらのものにはるかに優れています!!
fedorqui 'SO stop harming'

41

これにはtr -sコマンドを使います

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

これにより、すべての空白が1スペースに圧縮されます。このように、cutにスペースを区切り文字として使用するように指示すると、期待どおりに機能します。


1
私はこれが答えであるべきだと思います、それはOPリクエストに近いです(カットの使用を求められます)。この方法はawkの方法よりも5〜10%遅くなります(trで処理するパイプがもう1つあるため)。
Oliver

11

tr -s [:blank:]ベストアンサーとして推薦します。

なぜカットを使いたいのですか?「3番目のフィールドとその後のすべてのフィールドが必要で、最初の2つのフィールドは省略します」という魔法のコマンドがあります。

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

フィールドがいくつあるかわからない、つまりフィールドXから3番目のフィールドを出力するawkまたはperl splitの同等のコマンドがあるとは思いません。


9

より短い/より簡単な解決策:使用cuts(私が書いたステロイドをカット)

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

cutsフィールドインデックスはゼロベースであるため、5番目のフィールドは4と指定されていることに注意してください。

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

さらに短く(カットをまったく使用しない):

pgrep jboss

8

これを回避する1つの方法は、次のようにすることです。

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

複数の連続するスペースを1つのスペースに置き換える。


奇妙なことに、これはOS Xでは機能しません。sedコマンドは、複数のスペースを1つのスペースに変更しません。
rjurney 2016

2
\sGNU sed拡張機能です。OS X上では、渡すことができ-E、その後、拡張正規表現を有効に使用するためのsedにフラグを[[:space:]]代わりに\s:そうのように、sed -E 's/[[:space:]]+/ /g'
ジャレッドン

4

個人的には、このような仕事にはawkを使う傾向があります。例えば:

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

6
これはに圧縮できますps axu | awk '/[j]boss/ {print $5}'
zwol

1
awkが遅くなりませんか(特に、他に余分なプロセスがある場合)、sed / grep / cutですか?
pihentagy 2012

2

別の方法として、常にperlがあります。

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

または、フィールド#3から始まるすべてのフィールドを取得する場合(上記の回答の1つで述べたとおり):

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

これは、lsof私が試した出力では機能しません。これはlsof|perl -lane 'print $F[5]'、5列目、6列目になる場合があります
rubo77

問題は、さまざまな数のスペースを含む可能性のある区切り文字をどのように使用するかだったと思います。この目的のための答えは正しかった。
フリッツ

lsofの問題は、列の数が各行で常に一貫しているとは限らないことです。
フリッツ


2

ps出力から列を選択する場合は、-oを使用しない理由がありますか?

例えば

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

割り当てられた最小の列幅、パディングなし、単一のスペースフィールド区切りのみ。

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

10文字の幅、1つのスペースフィールド区切り文字を指定したPIDおよびvsz。

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

スクリプトで使用:-

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

0

カットコマンドを使用する必要がある場合の別の方法

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

Solarisでは、awkをnawkまたはに置き換えます/usr/xpg4/bin/awk


0

Perlが空白を含むフィールドを処理する方法は今でも好きです。
最初のフィールドは$ F [0]です。

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

0

私のアプローチは、PIDを/ tmp内のファイルに保存し、の-Sオプションを使用して適切なプロセスを見つけることですssh。それは誤用かもしれませんが、私にとってはうまくいきます。

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

SSH_PIDファイルが古く、誤ったプロセスを強制終了する可能性があるため、強制終了する前に権限を照会する方が適切なアプローチかもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.