文本处理的 sed 代码理解

文本处理的 sed 代码理解

谁能解释一下下面的 sed 代码

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*/\1/
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

我想编辑以添加“策略类型:”信息,当我将其替换为“策略名称:”时,它工作正常,但是,当我添加如下所示的部分时,它显然不起作用,因为我在不理解的情况下尝试它。

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
/Policy Type:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*/\1/
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

另外,我还有一个来自同一论坛的 AIX 等效代码的解决方案,我需要理解它才能编辑它以添加策略类型。

# define constants
SPC=`echo x | tr x '\040'`
TAB=`echo x | tr x '\011'`
 NL=

# custom regex for...
s="[$SPC$TAB]";   # horizontal whitespace
S="[^$SPC$TAB]";  # non-whitespace

# POSIX compliant sed code...
sed -ne "
   /Policy Name:/!d

   s/.*:$s\{1,\}//
   h

   :1
      n
      /Active:$s*no/d
   /HW\//!b1

   :2
      s/.*$s\($S*\)$s*/\1/
      G
      s/\n/$TAB/p
      n
      /^$s*\$/d
      /Include:/d
   b2
"  yourfile

输入文件

Policy Name:       Today

  Policy Type:       Standard
  Active:              yes
  Effective date:      01/24/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  EU         NY  Cindy
                 BU         CA  Victor
                 GU         MI  Bob
  Include:
Policy Name:       Tomorrow

  Policy Type:       Oracle
  Active:              yes
  Effective date:      01/26/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  MU         LA  Martha
                 EU         CA  Sam
  Include:
Policy Name:       Yesterday

  Policy Type:       Oracle
  Active:              no
  Effective date:      01/21/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  NV         IL  Joe

  Include:`

所需输出

Cindy    Today     Standard
Victor   Today     Standard
Bob      Today     Standard
Martha   Tomorrow  Oracle
Sam      Tomorrow  Oracle

答案1

好吧,让我们一步一步来:

sed -n '

除非另有说明,否则该-n选项不会输出任何内容sed

/Policy Name:/! d

所有不包含的行都Policy name:将被删除。脚本的其余部分仅在以下循环中处理。

s/.*:\s\+//
h

这将删除所有内容,直到:和 尾随空格,并将其余部分放入保留缓冲区中以供以后使用。

:1
n

这是读取新行的循环的开始

/Active:\s*no/d

具有该模式的线条被删除,因此显然对非活动没有兴趣

/HW\//!b1

现在,我们循环判断:1该行是否不包含HW/

:2
s/.*\s\(\S*\)\s*/\1/

下一个循环开始时,删除除最后一个非空白序列之外的所有内容。

G
s/\n/\t/p

然后附加保存在保留缓冲区中的策略名称,用制表符分隔并打印该行

n
/^\s*$\|Include:/! b2
'

这会在接下来的几行中重复,直到达到给定的模式。

您应该注意,这是高度不可移植的代码,无法在许多sed版本上运行。

编辑:要将策略类型添加为第三列,您应该在检查之前或之后将此行添加到脚本中Active:

/Policy Type:/{s/.*:\s*//;H;}

即:如果该行包含所述字符串,则执行 之间的命令{}。这些命令删除直到:和 尾随空白的部分,并将该行的其余部分(应该包含策略类型)附加到保留缓冲区。因此,保留缓冲区包含策略名称和类型,并以换行符分隔。因此,当我们将其附加到 时G,将会有两个换行符被替换,因此替换命令需要获取标志g来替换所有出现的情况:

s/\n/\t/gp

AIX 脚本基本相同,但避免了对正则表达式的 GNU 扩展。主要是使用变量来匹配空格或制表符,因为它\t不适用于所有sed风格,并且+“一个或多个”需要替换为\{1,\}

相关内容