AWK根据列号和模式匹配条件打印列

AWK根据列号和模式匹配条件打印列

我需要使用 awk 对静态和动态列号重新格式化以下命令的输出:

 ps -eopid,lstart,cmd | grep java |grep -v grep

以下是 awk 命令的示例输入:

17524 Wed May  9 08:50:37 2018 /opt/java/latest/bin/java -client -Xms256m -Xmx512m -XX:CompileThreshold=8000 -XX:PermSize=128m -XX:MaxPermSize=256m -Dweblogic.Name=AdminServer -Djava.security.policy=/app/oracle/wls1036/wlserver_10.3/server/lib/weblogic.policy -Dweblogic.system.BootIdentityFile=/projects/domainName/servers/AdminServer/security/boot.properties -Dweblogic.nodemanager.ServiceEnabled=true -Xverify:none -da -Dplatform.home=/app/oracle/wls1036/wlserver_10.3 -Dwls.home=/app/oracle/wls1036/wlserver_10.3/server -Dweblogic.home=/app/oracle/wls1036/wlserver_10.3/server -Ddomain.home=/projects/domainName -Does.client.home=/app/oracle/wls1036/oesclient -Doracle.home=/app/oracle/wls1036/oesclient -Doracle.security.jps.config=/projects/mydomain/config/oeswlssmconfig/AdminServer/jps-config.xml -Dweblogic.management.discover=true -Dwlw.iterativeDev= -Dwlw.testConsole= -Dwlw.logErrorsToConsole= -Dweblogic.ext.dirs=/app/oracle/wls1036/patch_wls1036/profiles/default/sysext_manifest_classpath:/app/oracle/wls1036/patch_ocp371/profiles/default/sysext_manifest_classpath weblogic.Server

示例输出:

24519 Wed May 9 23:50:09 2018 -Dweblogic.Name=AdminServer

问题:我可以使用 awk 根据列号打印初始 PID、启动日期和时间的值,但最后一个值的列号在某些情况下可能不同(例如:一个输出中的第 9 列和另一个输出中的第 17 列)。我如何打印搜索包含关键字“-Dweblogic.Name=”的相应列号的最后一个值并添加到现有输出。组合列号和列搜索的输出会引发异常。也欢迎使用任何更简单的方法来格式化此输出(sed、grep、cut 等)。

答案1

也许您可以使用 grep 搜索 Dweblogic,然后使用 sed 搜索

search="-Dweblogic.Name="
ps -eopid,lstart,cmd | \
grep "java.*$search" | \
sed -E 's#([^/]* )/.*('"$search"'[^ ]*).*#\1\2#'

答案2

要获取列,请使用循环

| awk '{for(i=NF;i>1;i--) 
     if ( $i ~ /-Dweblogic.name/ ) { wln=$i; break } ;
     printf "... %s ...",wln}'

在哪里

  • NF是代表字段的数量
  • for( )构造将从行尾循环到开始
  • $i ~ /-Dweblogic.name/匹配 -Dweblogic.name=admin1 , -Dweblogic.name=otheradmin (您可能希望 /^-D/ 与您自己不匹配)

我可以建议你放弃grep java | grep -v grep女巫grep [j]ava不会 grep 本身(并让同事感到惊讶),或者

| awk '/java/ {...} '

或者,拥有最大数量的 arg :

| awk '/java/ && NF>10 { ... }'

答案3

使用(以前称为 Perl_6)

raku -ne 'my @a = .words; put "@a[0..5] @a.grep(/^ \-Dweblogic\.Name\= /)" if .words > 6;' 

输入示例:

17524 Wed May  9 08:50:37 2018 /opt/java/latest/bin/java -client -Xms256m -Xmx512m -XX:CompileThreshold=8000 -XX:PermSize=128m -XX:MaxPermSize=256m -Dweblogic.Name=AdminServer -Djava.security.policy=/app/oracle/wls1036/wlserver_10.3/server/lib/weblogic.policy -Dweblogic.system.BootIdentityFile=/projects/domainName/servers/AdminServer/security/boot.properties -Dweblogic.nodemanager.ServiceEnabled=true -Xverify:none -da -Dplatform.home=/app/oracle/wls1036/wlserver_10.3 -Dwls.home=/app/oracle/wls1036/wlserver_10.3/server -Dweblogic.home=/app/oracle/wls1036/wlserver_10.3/server -Ddomain.home=/projects/domainName -Does.client.home=/app/oracle/wls1036/oesclient -Doracle.home=/app/oracle/wls1036/oesclient -Doracle.security.jps.config=/projects/mydomain/config/oeswlssmconfig/AdminServer/jps-config.xml -Dweblogic.management.discover=true -Dwlw.iterativeDev= -Dwlw.testConsole= -Dwlw.logErrorsToConsole= -Dweblogic.ext.dirs=/app/oracle/wls1036/patch_wls1036/profiles/default/sysext_manifest_classpath:/app/oracle/wls1036/patch_ocp371/profiles/default/sysext_manifest_classpath weblogic.Server

示例输出:

17524 Wed May 9 08:50:37 2018 -Dweblogic.Name=AdminServer

简而言之,-ne逐行输入被分解为空格分隔的words,并分配给@a数组。然后最初的 6 列(words [0..5])是 out put,然后是grepping 匹配正则表达式的完整单词/^ \-Dweblogic\.Name\= /(也可以写成:/^ "-Dweblogic.Name=" /)。

上面的代码处理输入中的短/空行,但即使/^ \-Dweblogic\.Name\= /未找到,它也会打印前 6 列(PID 和时间戳)。最好使用下面的代码,它使用 Raku 的$_主题变量克服了这个问题:

raku -ne 'my @a = .words; $_ = @a.grep(/^ \-Dweblogic\.Name\= /); put "@a[0..5] $_" if $_;' 

https://raku.org

相关内容