Com o GNU grep
, se construído com suporte a PCRE e assumindo que $string
não contém \E
, você pode fazer:
grep -P "^\Q$string"
Eu gostaria de usar fgrep
para lidar com palavras literais com períodos e outros meta-caracteres em grep
, mas preciso garantir que a palavra esteja no começo da linha.
Por exemplo, fgrep 'miss.'
corresponderá a miss.
exatamente o que eu quero, mas também admiss.
ou co. miss.
que eu não quero.
Eu posso escapar de meta-caracteres, por exemplo grep '^miss\.'
, mas a fonte é tão grande, estou fadado a perder alguma coisa e, em seguida, preciso executá-la novamente (demorará a noite toda). E em alguns casos, e. , o código de escape é aquele com "meta-significado".
Alguma maneira de contornar isso?
com awk
awk -vword='miss.' 'index($0, word) == 1' file
Para várias palavras
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
Eu também imagino python
para isso
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
Se os seus dados forem muito grandes, então grep
provavelmente será mais rápido que ferramentas mais flexíveis, como o awk. O que eu faria é citar os caracteres especiais no texto e chamar grep
.
pattern=$(printf '%s\n' "$literal_text" | sed 's/[\[.*^$]/\&/g')
grep "^$pattern" my-big-file
Se o texto contiver apenas caracteres ASCII, defina o conjunto de caracteres como C, para que o grep se preocupe apenas com bytes. Em algumas implementações (como muitas versões do GNU grep), os caracteres multi-byte podem causar uma grande penalidade de velocidade.
LC_CTYPE=C grep "^$pattern" my-big-file
Se você quiser pesquisar uma linha inteira exata, há uma opção para isso: grep -Fx -e "$literal_text"
. Mas isso corresponde apenas às linhas que consistem exatamente no texto especificado. Não há uma maneira semelhante de combinar linhas que começam com o texto especificado.
Se você não tem muitos padrões:
perl -ne 'BEGIN {$exp = quotemeta("miss.")} print if /^$exp/'
Eu não sei como estender isso eficientemente para grep -f
(padrões de leitura do arquivo, o que você faria se tivesse um número sério de padrões para lidar), mas esta resposta SO ao participar de consultas parece ser interessante.