fgrep início da linha?

4

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?

    
por Yimin Rong 21.01.2015 / 17:21

4 respostas

4

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"
    
por 22.01.2015 / 00:16
2

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 
    
por 21.01.2015 / 18:18
2

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.

    
por 22.01.2015 / 01:22
0

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.

    
por 21.01.2015 / 17:45