[英]sed/awk/perl formatting multiple paragraphs
dzinfo给我的输出格式如下:
User: x0000001
Forced into restricted environment: No
Role Name Avail Restricted Env
--------------- ----- --------------
login/Corp_All Yes None
_Example-Role-- Yes _Example-Role--
ALL_Servers-Win ALL_Servers-Win
/US_All /US_All
Domain_GLOBAL-Ro Yes Domain_GLOBAL-Ro
le-CORE_Group-AL le-CORE_Group-AL
L-MacOS/Domain_ L-MacOS/Domain_
GLOBAL GLOBAL
Effective rights:
Password login
Non password login
Allow normal shell
PAM Application Avail Source Roles
--------------- ----- --------------------
* Yes login/US_All
Privileged commands:
Name Avail Command Source Roles
--------------- ----- -------------------- --------------------
CORP_GLOBAL-Com Yes /usr/bin/getfacl CORP_GLOBAL-Role-COR
mand-CORE_SVR_I E_SVR_INFRA_ALL-LNX/
NFRA_ALL-V042-S CORP_GLOBAL
00042/CORP_GLOB
AL
CORP_GLOBAL-Com Yes /usr/bin/dzdo -l CORP_GLOBAL-Role-COR
mand-CORE_SVR_I E_SVR_INFRA_ALL-LNX/
NFRA_ALL-V042-S CORP_GLOBAL
00048/CORP_GLOB
AL
CORP_GLOBAL-Com Yes /bin/cp temp_auth CORP_GLOBAL-Role-COR
mand-CORE_SVR_I /home/sudocfg/author E_SVR_INFRA_ALL-LNX/
NFRA_ALL-V042-S ized_keys CORP_GLOBAL
00085/CORP_GLOB
AL
哪种工具是格式化报告的最佳选择? 我如何匹配/组合和格式化列/行,使其类似于以下内容?
User: x0000001
Forced into restricted environment: No
Role Name Avail Restricted Env
--------------- ----- --------------
login/Corp_All Yes None
_Example-Role--ALL_Servers-Win/US_All Yes _Example-Role--ALL_Servers-Win/US_All
Domain_GLOBAL-Role-CORE_Group-ALL-MacOS/Domain_GLOBAL Yes Domain_GLOBAL-Role-CORE_Group-ALL-MacOS/Domain_GLOBAL
Effective rights:
Password login
Non password login
Allow normal shell
PAM Application Avail Source Roles
--------------- ----- --------------------
* Yes login/US_All
Privileged commands:
Name Avail Command Source Roles
--------------- ----- -------------------- --------------------
CORP_GLOBAL-Command-CORE_SVR_INFRA_ALL-V042-S00042/CORP_GLOBAL Yes /usr/bin/getfacl CORP_GLOBAL-Role-CORE_SVR_INFRA_ALL-LNX/CORP_GLOBAL
CORP_GLOBAL-Command-CORE_SVR_INFRA_ALL-V042-S00048/CORP_GLOBAL Yes /usr/bin/dzdo -l CORP_GLOBAL-Role-CORE_SVR_INFRA_ALL-LNX/CORP_GLOBAL
CORP_GLOBAL-Command-CORE_SVR_INFRA_ALL-V042-S00085/CORP_GLOBAL Yes /bin/cp temp_auth /home/sudocfg/authorized_keys CORP_GLOBAL-Role-CORE_SVR_INFRA_ALL-LNX/CORP_GLOBAL
每列中的文本可以有很大的不同,所以我想自动调整宽度。
我可以处理一个班轮,但是要提供这样的报告? 我什至不知道从哪里开始。
首先,基本上是使用GNU awk for FIELDWIDTHS隔离每行上各个字段的方式:
$ cat tst.awk
BEGIN { origFS=FS }
/---/ {
origFS=FS
split($0,f,/\s+|-+/,s)
FIELDWIDTHS=""
for (i=1; i in s; i++) {
FIELDWIDTHS = (i>1 ? FIELDWIDTHS " " : "") length(s[i])
}
}
/^\s*$/ {
FIELDWIDTHS=""
FS=origFS
}
{
for (i=1; i<=NF; i++) {
printf "<%s>", $i, (i<NF?OFS:ORS)
}
print ""
}
。
$ awk -f tst.awk file
<User:><x0000001>
<Forced><into><restricted><environment:><No>
<Role><Name><Avail><Restricted><Env>
<---------------><-----><-------------->
< ><login/Corp_All >< ><Yes >< ><None >< >
< ><_Example-Role-->< ><Yes >< ><_Example-Role-><->
< ><ALL_Servers-Win>< >< >< ><ALL_Servers-Wi><n>
< ></US_All >< >< >< ></US_All ><>
< ><Domain_GLOBAL-R><o ><Yes >< ><Domain_GLOBAL-><R>
< ><le-CORE_Group-A><L >< >< ><le-CORE_Group-><A>
< ><L-MacOS/Domain_>< >< >< ><L-MacOS/Domain><_>
< ><GLOBAL >< >< >< ><GLOBAL ><>
<Effective><rights:>
<Password><login>
<Non><password><login>
<Allow><normal><shell>
<PAM><Application><Avail><Source><Roles>
<---------------><-----><-------------------->
<* >< ><Yes >< ><login/US_All >< >
<Privileged comm><an><ds:><><><>
< Name >< >< Ava><i><l Command >< >
< -------------><-->< ---><-><- ------------------><->
< ><CORP_GLOBAL-Com>< ><Yes >< ></usr/bin/getfacl >< ><CORP_GLOBAL-Role-COR>< >
< ><mand-CORE_SVR_I>< >< >< >< >< ><E_SVR_INFRA_ALL-LNX/>< >
< ><NFRA_ALL-V042-S>< >< >< >< >< ><CORP_GLOBAL >< >
< ><00042/CORP_GLOB>< >< >< >< >< >< >< >
< ><AL >< >< >< >< >< >< >< >
< ><CORP_GLOBAL-Com>< ><Yes >< ></usr/bin/dzdo -l >< ><CORP_GLOBAL-Role-COR>< >
< ><mand-CORE_SVR_I>< >< >< >< >< ><E_SVR_INFRA_ALL-LNX/>< >
< ><NFRA_ALL-V042-S>< >< >< >< >< ><CORP_GLOBAL >< >
< ><00048/CORP_GLOB>< >< >< >< >< >< >< >
< ><AL >< >< >< >< >< >< >< >
< ><CORP_GLOBAL-Com>< ><Yes >< ></bin/cp temp_auth >< ><CORP_GLOBAL-Role-COR>< >
< ><mand-CORE_SVR_I>< >< >< ></home/sudocfg/author>< ><E_SVR_INFRA_ALL-LNX/>< >
< ><NFRA_ALL-V042-S>< >< >< ><ized_keys >< ><CORP_GLOBAL >< >
< ><00085/CORP_GLOB>< >< >< >< >< >< >< >
< ><AL >< >< >< >< ><><><>
您将要购买Arnold Robbins所著的《有效的Awk编程》,第4版,并在开始进行修改以了解其工作原理并以此为基础时,方便参考。
我可以处理一个班轮,但是要提供这样的报告? 我什至不知道从哪里开始。
的确,单线很难做到这一点(除非这是一条很长的线)。 但是首先,可以分析问题并概述可能的解决方案。
以下Perl程序实现了一个解决方案。 但是请注意,由于它使用seek
,因此无法在管道输入上使用,而只能在文件上使用。
#!/usr/bin/perl -wn
if (/---/) # here comes a table
{
seek ARGV, $priprior, 0; # set position back to header line
push @gap, $-[1] while /(?<=-) *( )-/g; # find the column gaps
$tabrow = -1; # index of current table row: no rows yet
@maxlng = (0)x($#gap+2); # maximum length of text in each column
while (<>) # read the table, starting with headers
{ # check for end of table:
last if length() <= $gap[-1] or substr($_, $gap[-1], 1) ne ' ';
$offset = 0; # first column start
$contin = 0; # is it a continuation line?
foreach $i (0..$#gap+1)
{ # extract column:
if ($i <= $#gap) # not last column?
{ $column[$i] = substr $_, $offset, $gap[$i]-$offset;
$offset = $gap[$i];
}
else # last column
{ $column[$i] = substr $_, $offset;
}
$column[$i] =~ s/\s+$//; # remove trailing whitespace
$contin += $column[$i] eq '' # column empty?
}
++$tabrow unless $contin;
foreach $i (0..$#gap+1)
{ # ugly fix to restore the space in "temp_auth /home/...", where
# the column is wrapped early: --------------------
# ...
# /bin/cp temp_auth
# /home/sudocfg/author
# ized_keys
$table[$tabrow][$i] .= ' ' if $contin and length($table[1][$i])>
length($table[$tabrow][$i]);
# now that's fixed, proceed with normal unwrapping of the column
$column[$i] =~ s/^ +// if $contin or $i; # remove leading spaces
$table[$tabrow][$i] .= $column[$i];
$maxlng[$i] = length $table[$tabrow][$i] # update maximum length
if $maxlng[$i] < length $table[$tabrow][$i];
}
undef $_; last if eof
}
foreach $e (@table)
{
foreach $i (0..$#gap+1) { printf "%-*s", $maxlng[$i]+1, $$e[$i]; }
print "\n";
}
undef @gap; undef @table;
}
else { print $previous_line if $previous_line }
$previous_line = $_;
$priprior = $prior;
$prior = tell ARGV;
END { print $previous_line if $previous_line }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.