我想用来fgrep
处理搜索带有句点和其他元字符的文字单词grep
,但我需要确保该单词位于行的开头。
例如,fgrep 'miss.'
将完全匹配miss.
我想要的,但也admiss.
匹配co. miss.
我不想要的。
我也许能够转义元字符,例如grep '^miss\.'
,但是源太大了,我肯定会错过一些东西,然后需要再次运行它(将花费整个晚上)。在某些情况下,例如\1
,转义代码是具有“元含义”的代码。
有什么办法解决这个问题吗?
答案1
对于 GNU,grep
如果使用 PCRE 支持构建并假设$string
不包含\E
,您可以执行以下操作:
grep -P "^\Q$string"
与perl
的rindex
:
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
(从文件中读取模式,如果您有大量模式需要处理,您就会这样做),但是这个答案关于连接查询似乎很有趣。