Uma maneira é procurar por um dos nomes de arquivo (escolha o mais raro se você souber qual é) e filtrar as correspondências para reter apenas aquelas onde o outro arquivo existe.
find . -name foo -exec sh -c '[ -e "${0%/*}/bar" ] && [ -e "${0%/*}/buz" ] && echo "${0%/*}"' {} \;
Você pode usar o código de retorno do snippet de shell se desejar usar uma ação find
, mas isso se aplicaria ao primeiro arquivo, não ao diretório. Por exemplo, o seguinte snippet imprime a saída do formulário ./path/to/foo
:
find . -name foo -exec sh -c '[ -e "${0%/*}/bar" ] && [ -e "${0%/*}/buz" ]' {} \; -print
Se você precisar passar os nomes como argumentos:
find_multiple_files () {
root=$1; shift
name1=$2; shift
find "$root" -name "$name1" -exec sh -c 'dir=${0%/*}; for x; do [ -e "$dir/$x" ] || exit 1; done; echo "$dir"' {} "$@" \;
}
find_multiple_files . foo bar buz
Uma abordagem alternativa é gerar listas de nomes e filtrá-los. Isso é um pouco mais incômodo e menos eficiente, mas tem a vantagem de poder alternar de find
para locate
se você tiver um índice de nomes de arquivos. Presumo que os nomes dos arquivos não contenham novas linhas.
locate foo | # or: find -name foo
sed 's!/[^/]*$!!' |
xargs -I {} sh -c 'for x; do [ -e "$0/$x" ] || exit 1; done; echo "$0"' {} bar buz