有没有办法使用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
也不是我要找的,但是如何处理'cut'?
感谢。
答案 0 :(得分:268)
实际上awk
正是您应该关注的工具:
ps axu | grep '[j]boss' | awk '{print $5}'
或者你可以完全放弃grep
,因为awk
知道正则表达式:
ps axu | awk '/[j]boss/ {print $5}'
但是,如果由于某些奇怪的原因,你真的不能使用awk
,那么你可以做其他更简单的事情,比如首先将所有空格折叠到一个空格:< / p>
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 :(得分:91)
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
答案 2 :(得分:22)
我喜欢使用tr -s命令来实现这个
ps aux | tr -s [:blank:] | cut -d' ' -f3
这会将所有空白区域挤压到1个空间。这种方式告诉切割使用空格作为分隔符的方式符合预期。
答案 3 :(得分:8)
我将提名tr -s [:blank:]
作为最佳答案。
为什么我们要使用剪切?它有一个神奇的命令,说“我们想要第三个字段和后面的每个字段,省略前两个字段”
cat log | tr -s [:blank:] |cut -d' ' -f 3-
我不相信awk或perl split有一个等效的命令,我们不知道会有多少个字段,即将第3个字段放到字段X中。
答案 4 :(得分:7)
解决这个问题的一种方法是:
$ps axu | grep jboss | sed 's/\s\+/ /g' | cut -d' ' -f3
用一个空格替换多个连续的空格。
答案 5 :(得分:7)
cuts
(我写的类固醇减少)ps axu | grep '[j]boss' | cuts 4
请注意,cuts
字段索引从零开始,因此第5个字段指定为4
甚至更短(根本不使用剪切)是:
pgrep jboss
答案 6 :(得分:4)
就个人而言,我倾向于使用awk来完成这样的工作。例如:
ps axu| grep jboss | grep -v grep | awk '{print $5}'
答案 7 :(得分: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
Pid和vsz给定10个字符宽度,1个空格分隔符。
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})"
答案 8 :(得分:1)
作为替代方案,总有perl:
ps aux | perl -lane 'print $F[3]'
或者,如果你想让所有字段从字段#3开始(如上面的一个答案中所述):
ps aux | perl -lane 'print @F[3 .. scalar @F]'
答案 9 :(得分:0)
另一种方法,如果你必须使用剪切命令
ps axu | grep [j]boss |awk '$1=$1'|cut -d' ' -f5
在Solaris中,将awk替换为nawk
或/usr/xpg4/bin/awk
答案 10 :(得分:0)
我仍然喜欢Perl用空格处理字段的方式 第一个字段是$ F [0]。
$ ps axu | grep dbus | perl -lane 'print $F[4]'
答案 11 :(得分:0)
我的方法是将PID存储到/ tmp中的文件,并使用-S
的{{1}}选项查找正确的过程。这可能是滥用但对我有用。
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
,因为该文件可能是陈旧的,并且会导致错误的进程。