我需要使用 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
,然后是grep
ping 匹配正则表达式的完整单词/^ \-Dweblogic\.Name\= /
(也可以写成:/^ "-Dweblogic.Name=" /
)。
上面的代码处理输入中的短/空行,但即使/^ \-Dweblogic\.Name\= /
未找到,它也会打印前 6 列(PID 和时间戳)。最好使用下面的代码,它使用 Raku 的$_
主题变量克服了这个问题:
raku -ne 'my @a = .words; $_ = @a.grep(/^ \-Dweblogic\.Name\= /); put "@a[0..5] $_" if $_;'