com zsh :
has() ()(($#)) $REPLY/$~1(N)
ls -- **/*(/e{has Makefile}e{has \*.c})
has lá é definido como uma função que verifica se o glob dado como argumento resolve qualquer arquivo no diretório $REPLY . Usamos essa função no qualificador e glob para decidir se os diretórios são selecionados. Alguns dos recursos do zsh lá:
-
() {compound-command} arguments: função anônima. Aqui o código dessa função é(($#)), que retorna verdadeiro se o número de argumentos for diferente de zero -
$~1:zshnão divide + glob por padrão após a expansão do parâmetro. Você precisa solicitá-lo explicitamente$~1é para solicitar a parte glob sobre a expansão de$1, que é para$1para ser tomada como um padrão. -
(N): qualificador glob que ativa nullglob para aquele glob, que diz ao glob para expandir para nada se ele não corresponder a nenhum arquivo. -
**/: qualquer nível de subdiretórios -
(/e...): outro qualificador de glob, em que/corresponde apenas a arquivos do tipo diretório ee{code}que corresponde a arquivos para os quais o código é verdadeiro ( com o arquivo armazenado em$REPLY).
Adicione alguns qualificadores D glob se você quiser olhar para diretórios ocultos e considerar arquivos c ocultos:
printf '%s\n' **/*(D/e{has Makefile}e{'has "*.c(#qD)"'})
Com ferramentas GNU:
LC_ALL=C find . \( -name '*.c' -o -name Makefile \) -print0 |
LC_ALL=C awk -v RS='LC_ALL=C find . -name '.?*' -prune -o \( -name '*.c' -o -name Makefile \) -print0
' -v ORS='has() ()(($#)) $REPLY/$~1(N)
ls -- **/*(/e{has Makefile}e{has \*.c})
' '
{dirname = $0; sub("/[^/]*$", "", dirname)}
/\.c$/ {hasc[dirname]; next}
{hasMakefile[dirname]}
END {for (dir in hasc) if (dir in hasMakefile) print dir}' |
xargs -r0 ls
Se você não quiser descer em diretórios ocultos e não considerar arquivos C ocultos, altere o comando find para:
printf '%s\n' **/*(D/e{has Makefile}e{'has "*.c(#qD)"'})
Esses fornecerão o caminho e o conteúdo dos diretórios correspondentes, mas se houver apenas um diretório correspondente, ls não exibirá seu caminho. Você pode substituir ls -- por printf '%s\n' se desejar apenas os caminhos dos diretórios correspondentes.