如果一行包含字符串,Grep 保留(输出)整个 .txt 文件

如果一行包含字符串,Grep 保留(输出)整个 .txt 文件

我知道

grep -rhI "# Active" > out.txt 

将输出# Active包含搜索目录中的任何行,但我想要整个 .txt 文件内容,因此示例

示例.txt

Line1 
Line2
Line3 # Active
Line4
Line5
etc

因此,如果我 grep for# Active我希望它不仅输出这些 .txt 文件中包含的行# Active,还输出所有其他行,例如

输出.txt

Line1 
Line2
Line3 # Active
Line4
Line5
etc

答案1

对于非 GNU 版本的grep,不太可能有-z,或者如果需要可移植性......

grep -q pattern file && cat file

-q抑制任何输出,但通常情况下,退出状态是根据是否找到模式匹配来设置的。如果找到模式匹配,则grep返回成功代码0,相当于真的并且允许cat执行该命令。

答案2

通常,grep 只会显示匹配行:

$ grep -rhI "# Active"
Line3 # Active

要查看整个文件,请添加标志-z

$ grep -rhIz "# Active"
Line1 
Line2
Line3 # Active
Line4
Line5
etc

-z是一个 GNU 扩展,它告诉 grep 不要使用换行符作为“行”分隔符,而是使用 NUL 字符。由于文本文件中通常不包含 NUL 字符,因此这会告诉 grep 读取整个文件,就好像它是单个“行”一样。因此,如果存在匹配,则打印整个文件。

在 BSD/OSX 版本的 grep 上,NUL 输入选项不可用,并且-z有其他含义。

其他 grep 选项

-r告诉 grep 递归搜索文件和目录。

-I告诉 grep 忽略二进制文件

-h告诉 grep 打印匹配项而不附加文件名。

答案3

sed选择:

sed -e 'H;1h;/PATTERN/!d;x;:do' -e 'n;b do' infile

该脚本的工作原理是在旧缓冲区中累积行h(并删除它们),直到遇到匹配的行,此时它会x更改缓冲区并执行n(即打印并获取下一行),直到没有更多输入。

答案4

如果您想对多个文件执行此操作:

cat `grep -rIl "# Active" *`

Grep 将返回文件名列表,而 cat 将打印它们。

相关内容