谁能解释一下下面的 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,\}