如何很好地对齐显示表

Sas*_*Sas 5 linux bash awk

我正在尝试创建一个脚本,该脚本充当 ps 命令,并具有我想要显示的自己的属性。假设这是进程在 ps 命令中的样子:

sas 24431     1  0 Oct10 ?        00:51:08 /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs
Run Code Online (Sandbox Code Playgroud)

我想显示如下:

UID  PID    APPNAME
sas  24431  -Dapp.name=myApp
sas  24432  -Dapp.name=myApp2
sas  24433  -Dapp.name=myApp3
Run Code Online (Sandbox Code Playgroud)

注意:app.name属性是从 ps 命令中提取的命令参数

这是我的脚本:

echo -e "PID\tUSERID\t\tAPPNAME"
ps -u $USER -f |grep "java"|grep -v "grep"|
while read LINE 
do 
  #Get pid from the line
  PID=$(cut -d" " -f2 <<< $LINE);
  #Get parameter value called "-Dapp.name or -DprojectName" 
  #from the ps command for the process
  APPNAME=$(ps -f $PID | awk 'BEGIN {RS=" "}; /-Dapp.name|-DprojectName/');
  USERID=$(cut -d" " -f1 <<< $LINE);

 echo -e $PID"\t"$USERID"\t"$APPNAME;
done;
Run Code Online (Sandbox Code Playgroud)

现在它以我想要的方式工作。但有时对齐会被搞砸。也可以将此脚本优化为一行命令吗?

任何帮助,将不胜感激。

phe*_*mer 12

对于通用表格对齐,您需要该column实用程序。

例如:

(
 printf 'PID\tUSER\tAPPNAME\n'
 printf '%s\t%s\t%s\n' "1" "john" "foo bar"
 printf '%s\t%s\t%s\n' "12345678" "someone_with_a_long_name" "pop tart"
) | column -t -s $'\t'
Run Code Online (Sandbox Code Playgroud)

结果是:

PID       USER                      APPNAME
1         john                      foo bar
12345678  someone_with_a_long_name  pop tart
Run Code Online (Sandbox Code Playgroud)

  • 为了避免子shell,我们可以使用`{ cmd;}` (2认同)
  • 为了扩展@RahulPatil 的评论,`{printf ...;}` 比 `(printf ...)` 效率略高,因为 `()` 会产生一个子进程,而 `{}` 不会。如果在内部循环中使用该命令,这将变得相关,因为它可以产生数千个子进程。 (2认同)

ste*_*ver 3

另外这个脚本可以优化为一行命令吗?

我会考虑使用命令-o选项ps来输出(尽可能)仅感兴趣的字段,然后进行后处理以匹配java您需要的进程和特定命令参数 - 类似于

ps -u $USER -o uname=,pid=,args= | 
  gawk -vOFS='\t' '/java/ {print $1,$2,substr($0,match($0,"-D(app[.]name)|(projectName)[^[:space:]]*"),RLENGTH)}'
Run Code Online (Sandbox Code Playgroud)

或者也许是这样的perl免责声明:我的 Perl 知识很粗略

ps -u $USER -o uname=,pid=,args= | 
  perl -anle 'print join "\t", @F[0], @F[1], grep /-D(app[.]name)|(projectName)/,@F if /java/'
Run Code Online (Sandbox Code Playgroud)