Com o GNU awk você pode fazer:
awk 'BEGINFILE { n1=n2=0 }
/str1/ { n1=FNR }
/str2/ { n2=FNR }
ENDFILE { if (n1&&n2) print FILENAME,n1,n2 }
' files...
Uma variante para uma lista de strings a considerar:
awk -v s="str1 str2 str3" '
BEGIN { n=split(s,str) ; m=(2^n)-1 }
BEGINFILE { f=0 }
{ for (i=1; i<=n; i++)
if ($0 ~ str[i]) {
l[i] = FNR
f += 2^(i-1)
}
}
ENDFILE {
if (f==m)
for (i=1; i<=n; i++) print FILENAME,l[i]
}
' files...
Os comandos são melhor colocados em um arquivo de script para execução e substituindo a files...
list por "$@"
para passar os arquivos como argumentos para o script.
Um script, digamos "findall", para passar o diretório (conforme solicitado no comentário) e as sequências de pesquisa podem ser:
dir=${1:?}
shift
cd "$dir" || exit 1
awk -v s="$*" '
...as above...
' *
e coukd serão chamados findall dir str1 str2 ... strN
.
(Observe que as sequências de pesquisa podem não conter caracteres de espaço em branco.)