awk和grep的问题

时间:2010-10-31 15:09:21

标签: awk unix

我使用以下脚本来运行进程来打印id,命令..


if [ "`uname`" = "SunOS" ]  
then  
  awk_c="nawk"  
  ps_d="/usr/ucb/"  
  time_parameter=7  
else  
  awk_c="awk"  
  ps_d=""  
  time_parameter=5  
fi  

main_class=RiskEngine  
connection_string=db.regression  

AWK_CMD='BEGIN{printf "%-15s %-6s %-8s %s\n","ID","PID","STIME","Cmd"} {printf "%-15s %-6s %-8s %s %s %s\n","MY_APP",$2,$time_parameter, main_class, connection_string, port}'  

while getopts ":pnh" opt; do  
  case $opt in  
    p) AWK_CMD='{ print $2 }'  
       do_print_message=1;;  
    n) AWK_CMD='{printf "%-15s %-6s %-8s %s %s %s\n","MY_APP",$2,$time_parameter,main_class, connection_string, port}' ;;  
    h) print "usage  :  `basename ${0}` {-p} {-n}    : Returns details of process running "  
       print "  -p   :   Returns a list of PIDS"  
       print "  -n   :   Returns process list without preceding header"  
       exit 1 ;  

  esac  
done  

ps auxwww | grep $main_class | grep 10348 | grep -v grep | ${awk_c} -v main_class=$merlin_main_class -v connection_string=$merlin_connection_
string -v port=10348 -v time_parameter=$time_parameter "$AWK_CMD"  

# cat /etc/redhat-release  
Red Hat Enterprise Linux AS release 4 (Nahant Update 6)  
# uname -a  
Linux deapp25v 2.6.9-67.0.4.EL #1 Fri Jan 18 04:49:54 EST 2008 x86_64 x86_64 x86_64 GNU/Linux  

当我独立地或在脚本

内从脚本执行以下操作时
# ps auxwww | grep $main_class | grep 10348 | grep -v grep | ${awk_c} -v main_class=$merlin_main_class -v connection_string=$merlin_connection_string -v port=10348 -v time_parameter=$time_parameter "$AWK_CMD"  

我在Linux上获得了两行:

ID              PID    STIME    Cmd  
MY_APP      6217   2355352   RiskEngine 10348  
MY_APP      21874  5316      RiskEngine 10348  

我只有一个jvm(Java命令)在后台运行,但我仍然看到2行。

我知道其中一个(使用pid 21874复制)来自我正在执行的awk命令。它再次包括主类和端口两行。你能帮我避免重复一行吗?

你能帮帮我吗?

4 个答案:

答案 0 :(得分:2)

AWK可以为您完成所有的操作。

以下是AWK命令如何选择的简单示例:

ps auxww | awk -v select="$mainclass" '$0 ~ select && /10348/ && ! (/grep/ || /awk/) && {print}'

ps可以选择性地输出有助于减少误报的字段。但是pgrep对您来说可能更有用,因为您实际使用的只是结果中的PID。

pgrep -f "$mainclass.*10348"

答案 1 :(得分:0)

您已在代码中使用grep -v grep技巧,为什么不更新它以排除awk进程以及grep -v ${awk_c}

换句话说,脚本的最后一行是(在一行上,使用真实的命令参数到awk而不是blah blah blah)。:

ps auxwww
    | grep $main_class
    | grep 10348
    | grep -v grep
    | grep -v ${awk_c}
    | ${awk_c} -v blah blah blah

这将确保进程列表不会包含任何单词awk

请记住,以这种方式执行此操作并不总是一个好主意(误报),但是,由于您已经承担了包含grep的流程的风险,因此您可以使用包含awk的流程{{1}}也是如此。

答案 2 :(得分:0)

我已将代码重新格式化为代码,但您需要了解返回密钥是您的朋友。巨大的长管道应该分成多行 - 我通常在管道中每个命令使用一行。您还可以在多行上编写awk脚本。这使您的代码更具可读性。

然后你需要向我们解释你的目标。

但是,您很可能在grep上使用'awk'作为变体,并且发现值10348(可能在某些命令行上用作端口号)也在{的输出中{1}}作为ps的参数之一(与'main_class'值一样),因此您可以获得额外的信息。您需要修改awk脚本以消除(忽略)包含'awk'的行。

请注意,如果碰巧由一个PID或PPID等于10348的进程运行,您仍然可以通过在端口9999上运行主类的命令(10348以外的任何值)进行操作。如果您是要彻底完成这项工作,那么'awk'脚本只需要分析该行的'command plus options'部分。

答案 3 :(得分:0)

您可以在所有awk args前添加此简单代码:   '!/ awk / {....原始awk代码....}'

'!/ awk /'会告诉awk忽略包含字符串awk的任何行。

如果您将我的awk建议扩展为以下内容,您也可以删除'grep -v':  '!/ / awk /&& !/ grep / {...原始awk代码......}'。