如何在忽略换行符的文件中搜索文本?

Nik*_*yks 13 grep search text-processing newlines

我想搜索可能在文件中分成几行的文本。将忽略换行符并返回匹配行跨度的 grep。

例如,我会搜索is an example file,并希望在以下文件中找到它:

这是
一个
示例文件。

不要依赖前导或尾随空格,完全忽略所有形式的空格可能是最好的(理想情况下,将任何空格序列视为单个空格)。


一种非理想的解决方案是tr '\n' ' ' | grep,它区分匹配和非匹配,但不显示匹配,也不能很好地处理大文件。

Cos*_*tas 14

GNUgrep可以做到

grep -z 'is\san\sexample\sfile.' file
Run Code Online (Sandbox Code Playgroud)

为了满足评论中出现的一些要点,对脚本进行了一些修改:

 grep -oz '^[^\n]*\bis\s*an\s*example\s*file\.[^\n]*' file
Run Code Online (Sandbox Code Playgroud)

关于大文件,我对内存限制没有想象,但在出现问题的情况下你可以自由使用 sed

sed '/\bis\b/{
          :1
          N
          /file\.\|\(\n.*\)\{3\}/!b1
         }
     /\<is\s*an\s*example\s*file\./p
     D' file
Run Code Online (Sandbox Code Playgroud)

在内存中保留不超过 4 行(因为模式中有 4 个单词)(\(\n.*\)\{3\})。

  • 我相信你知道,`-z` 选项告诉 `grep` 将换行符视为普通文本字符,并查找空字节来分隔记录。在没有空字节的文本文件中(即典型情况),`grep -z` 会将整个文件视为一行。所以 (1) 这提出了它处理大文件的能力的问题,以及 (2) 如果找到匹配,它将写出整个文件,不提供匹配位置的线索。另外 (3) OP 说,“理想情况下,将任何空格序列视为单个空格”,因此您应该使用 `\s+` 并添加 `-E`。 (6认同)

lcd*_*047 7

尝试这个:

pcregrep -M '\bThis\s+is\b' <<EOT
This
is
an example
file.
EOT
Run Code Online (Sandbox Code Playgroud)

  • 然后你可以这样做:`pcregrep -M "$( echo 'This is a very long pattern' | sed 's/ /\\s+/g' )" file`。 (2认同)