如何用sed实现双条件行过滤?兼谈grep与sed颜色叠加异常
用sed按两个条件过滤行
如果想要过滤出同时满足两个条件的行(比如既是Package:开头,又包含grep的行),可以用这两种sed实现方式:
方法1:嵌套地址匹配
aptitude search grep | sed -n '/^Package:/{/grep/p}'
解释一下:
-n让sed只打印我们指定的行/^Package:/{...}:对所有以Package:开头的行,执行花括号里的命令/grep/p:在这些行里,只打印包含grep的行
方法2:合并正则表达式匹配
如果两个条件可以整合成一个正则,写法更简洁:
aptitude search grep | sed -n '/^Package:.*grep/p'
这个正则的意思是:匹配以Package:开头,且后面任意位置包含grep的行。
解决颜色标记的冲突问题
你遇到的颜色异常,核心原因是颜色重置序列\e[0m会关闭所有已设置的颜色格式。当你先给grep加上红色+全局重置,再给整个Package:行套黄色时,行内的\e[0m会把黄色也关掉,导致后面的内容变回默认颜色。
下面是两种实用的sed解决思路:
思路1:调整处理顺序,优先给行加黄色,再处理行内grep
aptitude search grep | sed ' # 处理Package行:先加黄色前缀,替换grep为红色+黄色后缀,最后加全局重置 /^Package:/ { s/^\(.*\)/\x1b[33m\1/ s/grep/\x1b[31mgrep\x1b[33m/g s/$/\x1b[0m/ } # 处理非Package行的grep:直接加红色+全局重置 /^Package:/! s/grep/\x1b[31mgrep\x1b[0m/g '
原理说明:
- 对
Package:行,先给整个行加上黄色前缀\x1b[33m - 把行内的
grep替换为红色\x1b[31mgrep,之后立刻恢复黄色\x1b[33m(而不是全局重置) - 最后在行尾加全局重置
\x1b[0m,确保后续内容回到默认格式 - 非Package行的
grep直接用红色+全局重置即可,没有冲突
思路2:用临时标记避免提前关闭颜色
如果需要更灵活的控制,可以用sed的临时标记暂存状态:
aptitude search grep | sed ' # 先把所有grep标记为红色(用\x1b[K做临时占位) s/grep/\x1b[31mgrep\x1b[K/g # 对Package行,包裹黄色前缀和重置后缀 /^Package:/ { s/^/\x1b[33m/ s/$/\x1b[0m/ } # 对非Package行,把临时占位换成全局重置 /^Package:/! s/\x1b[K/\x1b[0m/g '
这里用\x1b[K作为临时标记,最后再根据行类型替换成对应的重置序列,避免提前关闭颜色。
另外,用awk实现逻辑会更直观,也能解决这个问题:
aptitude search grep | awk ' BEGIN { RED = "\033[31m"; YELLOW = "\033[33m"; RESET = "\033[0m"; } /^Package:/ { # 先替换行内的grep为红色+黄色 gsub(/grep/, RED "&" YELLOW); # 包裹整个行为黄色+重置 print YELLOW $0 RESET; next; } { # 非Package行直接替换grep为红色+重置 gsub(/grep/, RED "&" RESET); print; } '
内容的提问来源于stack exchange,提问作者Ray Andrews
相关产品推荐
相关产品推荐

