Aqui está uma visão geral dos diferentes métodos que se pode usar para pesquisar arquivos por sequências de texto específicas, com algumas opções adicionadas especificamente para trabalhar apenas com arquivos de texto e ignorar arquivos binários / de aplicativos.
Deve-se notar, no entanto, que a busca por palavras pode se tornar um pouco complexa, porque a maioria das ferramentas de correspondência de linhas tentará encontrar uma palavra em qualquer lugar da linha. Se estamos falando de uma palavra como string que pode aparecer no início ou no final da linha, ou sozinha na linha, ou cercada por espaços e / ou pontuação - é quando precisaremos de expressões regulares e, especialmente, as que vierem de Perl. Aqui, por exemplo, podemos usar -P
em grep
fazer uso de expressões regulares Perl para cercá-lo.
$ printf "A-well-a don't you know about the bird?\nWell, everybody knows that the bird is a word" | grep -noP '\bbird\b'
1:bird
2:bird
Grep simples
$ grep -rIH 'word'
-r
para pesquisa recursiva no diretório atual
-I
ignorar arquivos binários
-H
para gerar o nome do arquivo onde a correspondência é encontrada
Adequado apenas para pesquisa.
find + grep
$ find -type f -exec grep -IH 'word' {} \;
find
a parte de pesquisa recursiva
-I
opção é ignorar arquivos binários
-H
para gerar o nome do arquivo onde a linha é encontrada
boa abordagem para combinar com outros comandos no subshell, como:
$ find -type f -exec sh -c 'grep -IHq "word" "$1" && echo "Found in $1"' sh {} \;
Perl
#!/usr/bin/env perl
use File::Find;
use strict;
use warnings;
sub find_word{
return unless -f;
if (open(my $fh, $File::Find::name)){
while(my $line = <$fh>){
if ($line =~ /\bword\b/){
printf "%s\n", $File::Find::name;
close($fh);
return;
}
}
}
}
# this assumes we're going down from current working directory
find({ wanted => \&find_word, no_chdir => 1 },".")
grep recursivo de pobre-homem no script bash recursivo
Este é o "caminho da festa". Não é o ideal, provavelmente não há um bom motivo para usar isso quando você tiver grep
ou estiver perl
instalado.
#!/usr/bin/env bash
shopt -s globstar
#set -x
grep_line(){
# note that this is simple pattern matching
# If we wanted to search for whole words, we could use
# word|word\ |\ word|\ word\ )
# although when we consider punctuation characters as well - it gets more
# complex
case "$1" in
*word*) printf "%s\n" "$2";;
esac
}
readlines(){
# line count variable can be used to output on which line match occured
#line_count=1
while IFS= read -r line;
do
grep_line "$line" "$filename"
#line_count=$(($line_count+1))
done < "$1"
}
is_text_file(){
# alternatively, mimetype command could be used
# with *\ text\/* as pattern in case statement
case "$(file -b --mime-type "$1")" in
text\/*) return 0;;
*) return 1;;
esac
}
main(){
for filename in ./**/*
do
if [ -f "$filename" ] && is_text_file "$filename"
then
readlines "$filename"
fi
done
}
main "$@"
grep -r word .
.