簡単な方法の 1 つは、tr
のパスを追加することです。 繰り返されるフィールドセパレーターを絞り出す:
$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4
tr -s ' '
に注意してください オプションは、単一の先行スペースを削除しません。列が右揃えの場合 (ps
のように) pid)...
$ ps h -o pid,user -C ssh,sshd | tr -s " "
1543 root
19645 root
19731 root
次に、最初の列である場合、一部のフィールドを切り取ると空白行になります:
$ <previous command> | cut -d ' ' -f1
19645
19731
前にスペースを入れない限り、明らかに
$ <command> | sed -e "s/.*/ &/" | tr -s " "
ここで、pid 番号 (名前ではない) のこの特定のケースに対して、pgrep
という関数があります。 :
$ pgrep ssh
シェル関数
ただし、一般的には シェル関数 を使用することはまだ可能です read
にはきちんとしたことがあるので、簡潔に説明します。 コマンド:
$ <command> | while read a b; do echo $a; done
読み取る最初のパラメーター、a
、最初の列を選択し、さらにある場合は その他すべて b
に入れられます .その結果、列の数よりも多くの変数が必要になることはありません +1 .
だから、
while read a b c d; do echo $c; done
次に、3 列目を出力します。私のコメントに示されているように...
呼び出しスクリプトに変数を渡さない環境では、パイプ読み取りが実行されます。
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'`
配列ソリューション
そのため、@frayser による回答で終わります。これは、デフォルトでスペースに設定されているシェル変数 IFS を使用して、文字列を配列に分割することです。ただし、Bashでのみ機能します。 Dash と Ash はサポートしていません。 Busybox で文字列をコンポーネントに分割するのに本当に苦労しました。単一のコンポーネントを取得し (awk を使用するなど)、必要なすべてのパラメーターに対してそれを繰り返すのは簡単です。しかし、その後、同じ行で awk を繰り返し呼び出すか、同じ行で echo を使用して読み取りブロックを繰り返し使用することになります。これは効率的でもきれいでもありません。したがって、 ${name%% *}
を使用して分割することになります 等々。使い慣れた機能の半分以上がなくなってしまうと、シェル スクリプトはもはや楽しくなくなるため、Python のスキルが欲しくなります。しかし、そのようなシステムには python でさえインストールされないだろうと推測できますし、そうではありませんでした;-)
最も簡単な方法は awk を使用することだと思います .例:
$ echo "11383 pts/1 00:00:00 bash" | awk '{ print $4; }'
bash