fgrep 行首?

fgrep 行首?

我想用来fgrep处理搜索带有句点和其他元字符的文字单词grep,但我需要确保该单词位于行的开头。

例如,fgrep 'miss.'将完全匹配miss.我想要的,但也admiss.匹配co. miss.我不想要的。

我也许能够转义元字符,例如grep '^miss\.',但是源太大了,我肯定会错过一些东西,然后需要再次运行它(将花费整个晚上)。在某些情况下,例如\1,转义代码是具有“元含义”的代码。

有什么办法解决这个问题吗?

答案1

对于 GNU,grep如果使用 PCRE 支持构建并假设$string不包含\E,您可以执行以下操作:

grep -P "^\Q$string"

perlrindex:

perl -sne 'print if rindex($_, $string, 0) == 0' -- -string="$string"

awk

S=$string awk 'index($0, ENVIRON["S"]) == 1'

答案2

如果您的数据非常大,那么grep可能比 awk 等更灵活的工具更快。我要做的就是引用文本中的特殊字符并调用grep.

pattern=$(printf '%s\n' "$literal_text" | sed 's/[\[.*^$]/\\&/g')
grep "^$pattern" my-big-file

如果文本只包含 ASCII 字符,则将字符集设置为 C,以便 grep 只关心字节。在某些实现中(例如 GNU grep 的许多版本),多字节字符可能会导致显着的速度损失。

LC_CTYPE=C grep "^$pattern" my-big-file

如果您想搜索精确的整行,那么有一个选项:grep -Fx -e "$literal_text"。但这仅匹配完全由指定文本组成的行,没有类似的方法来匹配以指定文本开头的行。

答案3

awk

awk -vword='miss.' 'index($0, word) == 1' file

对于多个单词

awk 'BEGIN{for (i=2; i<ARGC; ++i)word[++j]=ARGV[i]; ARGC=2}
    {for (i=1; i<=j; ++i)if (index($0, word[i]) == 1){print; continue}}' file \
    word1 word2 word3

我也喜欢python这个

python3 -c 'import sys
words = tuple(sys.argv[1:])
for line in sys.stdin:
  print(line if line.startswith(words) else "", end="")
' <file word1 word2 word3 

答案4

如果您没有太多模式:

perl -ne 'BEGIN {$exp = quotemeta("miss.")} print if /^$exp/'

我不知道如何有效地将其扩展到grep -f(从文件中读取模式,如果您有大量模式需要处理,您就会这样做),但是这个答案关于连接查询似乎很有趣。

相关内容