Skip to main content
added 599 characters in body
Source Link
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k

One could call an in-line script for each directory. The script would check whether the pattern matches any regular files in the directory. If the pattern matches, it outputs (in the general case, processes rather than just print) the matching pathnames and prunes the parent directory from the search tree:

find /top/dir -type d -exec zsh -c '
    set -- "$1"/pattern(.N)
    [[ $# -eq 0 ]] && exit 1
    printf "%s\n" "$@"' zsh {} \; -prune

I'm using the zsh shell for the in-line script to access that shell's globbing qualifiers. The qualifier used here, (.N), ensures that only regular files match the pattern and removes the pattern if there are no matching files.


Using bash for the in-line script:

find /top/dir -type d -exec bash -O nullglob -c '
    unset -v found
    for pathname in "$1"/pattern; do
        if [[ -f "$pathname" ]] && [[ ! -h "$pathname" ]]; then
            printf "%s\n" "$pathname"
            found=true
        fi
    done
    "${found-false}"' bash {} \; -prune

That is, let the in-line script loop over the names matching the pattern in the specific directory, and if any name corresponds to a regular file, process it and set a "flag". If the flag is set at the end, prune the parent directory.

One could call an in-line script for each directory. The script would check whether the pattern matches any regular files in the directory. If the pattern matches, it outputs (in the general case, processes rather than just print) the matching pathnames and prunes the parent directory from the search tree:

find /top/dir -type d -exec zsh -c '
    set -- "$1"/pattern(.N)
    [[ $# -eq 0 ]] && exit 1
    printf "%s\n" "$@"' zsh {} \; -prune

I'm using the zsh shell for the in-line script to access that shell's globbing qualifiers. The qualifier used here, (.N), ensures that only regular files match the pattern and removes the pattern if there are no matching files.

One could call an in-line script for each directory. The script would check whether the pattern matches any regular files in the directory. If the pattern matches, it outputs (in the general case, processes rather than just print) the matching pathnames and prunes the parent directory from the search tree:

find /top/dir -type d -exec zsh -c '
    set -- "$1"/pattern(.N)
    [[ $# -eq 0 ]] && exit 1
    printf "%s\n" "$@"' zsh {} \; -prune

I'm using the zsh shell for the in-line script to access that shell's globbing qualifiers. The qualifier used here, (.N), ensures that only regular files match the pattern and removes the pattern if there are no matching files.


Using bash for the in-line script:

find /top/dir -type d -exec bash -O nullglob -c '
    unset -v found
    for pathname in "$1"/pattern; do
        if [[ -f "$pathname" ]] && [[ ! -h "$pathname" ]]; then
            printf "%s\n" "$pathname"
            found=true
        fi
    done
    "${found-false}"' bash {} \; -prune

That is, let the in-line script loop over the names matching the pattern in the specific directory, and if any name corresponds to a regular file, process it and set a "flag". If the flag is set at the end, prune the parent directory.

Source Link
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k

One could call an in-line script for each directory. The script would check whether the pattern matches any regular files in the directory. If the pattern matches, it outputs (in the general case, processes rather than just print) the matching pathnames and prunes the parent directory from the search tree:

find /top/dir -type d -exec zsh -c '
    set -- "$1"/pattern(.N)
    [[ $# -eq 0 ]] && exit 1
    printf "%s\n" "$@"' zsh {} \; -prune

I'm using the zsh shell for the in-line script to access that shell's globbing qualifiers. The qualifier used here, (.N), ensures that only regular files match the pattern and removes the pattern if there are no matching files.