Some alternative approaches to be able to run arbitrary shell code instead of just [ -f "$d/${d##*/}.md" ]:
Pass the shell code as the first argument and use eval to interpret it:
FIND(){
find . -type d -exec sh -c '
code=$1; shift
for d do
eval "$code" && printf "%s\n" "$d"
done' find-sh "$1" {} +
}
FIND '[ -f "$d/${d##*/}.doc" ]'
Same with an environment variable
FIND(){
CODE=$1 find . -type d -exec sh -c '
for d do
eval "$CODE" && printf "%s\n" "$d"
done' find-sh "$1" {} +
}
FIND 'base=${d##*/}; [ -f "$d/$base.md" ] && [ -f "$d/$base.doc" ]'
Of if the shell code to interpret is always going to be [ -f "something" ]:
FIND(){
FILE_TEST=$1 find . -type d -exec sh -c '
for d do
eval "[ -f \"$FILE_TEST\" ]" && printf "%s\n" "$d"
done' find-sh "$1" {} +
}
FIND '$d/${d##*/}.doc'
Note that if using zsh, you can just use it'sits e glob qualifier to further qualify the directories (/) with an arbitrary shell expression:
print -rC1 ./**/*(ND/e['[ -f $REPLY/$REPLY:t.md ]'])
Or with a function:
has_md() [ -f $REPLY/$REPLY:t.md ]
print -rC1 ./**/*(ND/+has_md)
(N for nullglob, D for dotglob to not ignore hidden files and dirs)