Dav*_* T. 3 regex bash awk grep sed
我有一个看起来像这样的文件:
# cat $file
...
ip access-list extended DOG-IN
permit icmp 10.10.10.1 0.0.0.7 any
permit tcp 10.11.10.1 0.0.0.7 eq www 443 10.12.10.0 0.0.0.63
deny ip any any log
ip access-list extended CAT-IN
permit icmp 10.13.10.0 0.0.0.255 any
permit ip 10.14.10.0 0.0.0.255 host 10.15.10.10
permit tcp 10.16.10.0 0.0.0.255 host 10.17.10.10 eq smtp
...
Run Code Online (Sandbox Code Playgroud)
我希望能够按名称搜索(使用脚本)以获得独立访问列表的“部分”输出。我希望输出看起来像这样:
# grep -i dog $file | sed <options??>
ip access-list extended DOG-IN
permit icmp 10.10.10.1 0.0.0.7 any
permit tcp 10.11.10.1 0.0.0.7 eq www 443 10.12.10.0 0.0.0.63
deny ip any any log
Run Code Online (Sandbox Code Playgroud)
...不再输出不适用的非缩进行。
我已经尝试过以下方法:
grep -A 10 DOG $file | sed -n '/^[[:space:]]\{1\}/p'
Run Code Online (Sandbox Code Playgroud)
...这只给出了 DOG 之后以单个空格开头的 10 行(包括不适用于搜索的访问列表的行)。
sed -n '/DOG/,/^[[:space:]]\{1\}/p' $file
Run Code Online (Sandbox Code Playgroud)
...这给了我包含 DOG 的行,以及以单个空格开头的下一行。(需要访问列表的所有适用行...)
我想要包含 DOG 的行,以及 DOG 之后以单个空格开头的所有行,直到下一个未缩进的行。内容中有太多变量,无法依赖于除前导空格之外的任何模式(末尾并不总是否认,等等......)。
使用GNU sed (Linux):
name='dog' # case-INsensitive name of section to extract
sed -n "/$name/I,/^[^[:space:]]/ { /$name/I {p;d}; /^[^[:space:]]/q; p }" file
Run Code Online (Sandbox Code Playgroud)
要使匹配区分大小写,请删除上面I出现的后面的内容/I。
-n抑制默认输出,以便必须使用诸如 之类的函数在脚本内显式请求输出p。"...") sed,以便允许引用shell变量$name:双引号确保 shell 变量引用在脚本被传递之前展开sed(sed本身无法访问 shell 变量)。
sed元字符,例如,$并且\$(b) shell 变量值不得包含可能sed破坏sed脚本的元字符;对于在sed脚本中使用的 shell 变量值的通用转义,请参阅我的这个答案,或使用我的awk基于答案。/$name/I,/^[^[:space:]]/使用一个范围来匹配感兴趣的行(/$name/I; 尾随I是 GNUsed的不区分大小写的匹配选项)到下一节的开头( -/^[^[:space:]]/即不以空格开头的下一行);由于sed范围始终包含在内,因此挑战是有选择地删除范围的最后一行(如果它是下一部分的开始)-请注意,如果感兴趣的部分是文件中的最后一个部分,则不会出现这种情况。{ ... }仅针对范围内的每一行执行。/$name/I {p;d};无条件打印范围的第一行:d删除该行(已打印)并开始下一个循环(继续到下一个输入行)。/^[^[:space:]]/q匹配范围中的最后一行,如果它是下一部分的第一行,则完全退出处理 ( q),而不打印该行。p然后仅到达部分内部线并打印它们。笔记:
awk基于答案。FreeBSD/macOSsed几乎可以做同样的事情,只是它缺少不区分大小写的选项I。
name='DOG' # case-SENSITIVE name of section to extract
sed -n -e "/$name/,/^[^[:space:]]/ { /$name/ {p;d;}; /^[^[:space:]]/q; p; }" file
Run Code Online (Sandbox Code Playgroud)
请注意,FreeBSD/OSXsed通常具有更严格的语法要求,例如;命令后即使后跟}.
如果您确实需要不区分大小写,请参阅我的awk答案。