Para obter a lista de nomes de arquivos que grep
corresponde, você pode usar a opção -l
para obter apenas o nome do arquivo, não é necessário usar awk
para processar a saída. Isso também é mais rápido no caso de arquivos correspondentes, pois grep
pode parar depois que o padrão é encontrado uma vez.
grep -le "$searchtext" ./*
Você pode colocar a saída disso em uma variável, com atribuição simples (mas nomes de arquivos com espaços em branco e caracteres glob causam problemas):
files=$(grep -le "$searchtext" ./* )
Quanto a isso:
find . -type f -exec head -n 30 {} + | grep "$searchtext"
O canal aqui separa o find
e o grep
, portanto, você está efetivamente concatenando as primeiras 30 linhas de cada arquivo (perdendo o controle dos nomes dos arquivos aqui) e, em seguida, aplicando o resultado. grep -l
só pode dizer se existem correspondências em toda a entrada. Você precisaria executar um shell a partir de find
para combinar os head
e grep
para cada arquivo individualmente:
export searchtext
find . -type f -exec sh -c 'head -n 30 "$1" | grep -q "$searchtext" && echo "$1"' sh {} \;
Mas também podemos usar awk
para fazer isso. Isso procuraria o padrão apenas nas primeiras 30 linhas (GNU awk):
awk -vpattern="$searchtext" 'FNR <= 30 && $0 ~ pattern { print FILENAME; nextfile }' *
ou com o find:
find . -type f -exec awk -vpattern="$searchtext" 'FNR <= 4 && $0 ~ pattern { print FILENAME; nextfile }' {} +