繁体   English   中英

sed / awk / perl格式化多个段落

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM