#!/usr/bin/env bash # # Copyright (c) 2014, Ray Donnelly # # Usage: pacman-rec-filename-grep || # # Name of Pacman package or group to search in. # # Filename to write to. Pass '-' to use stdout. # # Optional extended regex to fnmatch using grep. # Defaults to matching all files by using '.*$' # # Exitcode: Only fails if less than two arguments are passed or when # outfile is not writable. Otherwise succeeds, even if the # package/group doesn't exist, where you just get an empty # outfile (or no output to stdout). # # Example: To get a list of all the .dlls in the base group, use: # pacman-rec-filename-grep base base-dlls.txt ".*\.dll$" pkg_or_group=$1; shift outfile=$1; shift regex=$1 # Defaults to matching all filenames. [[ -z "${regex}" ]] && regex=".*$" debug=0 declare -a dependencies declare -a new_dependencies # Maybe it's a group .. pacman -Sg $pkg_or_group > /dev/null 2>&1 && new_dependencies=($(pacman -Sg $pkg_or_group | cut -d' ' -f2)) # .. or maybe it's a package. pacman -Qi $pkg_or_group > /dev/null 2>&1 && new_dependencies=("${pkg_or_group}") while [[ ${#dependencies[@]} -ne ${#new_dependencies[@]} ]]; do [[ debug -eq 1 ]] && echo "sizes are dependencies=${#dependencies[@]} and new_dependencies=${#new_dependencies[@]}" dependencies=(${new_dependencies[@]}) new_dependencies=() for package in ${dependencies[@]}; do new_dependencies+=("${package}") pkg_deps=$(pacman -Si ${package} 2>/dev/null | sed -n "s/^Depends On \+:\(.*\)$/\1/p") [[ debug -eq 1 ]] && echo "Dependencies of ${package} are ${pkg_deps}" for pkg_dep in $pkg_deps; do new_package=${pkg_dep%>=*} new_dependencies+=("${new_package}") done done [[ debug -eq 1 ]] && echo "new_dependencies (pre-sorting) ${new_dependencies[@]}" new_dependencies=($(printf "%s\n" "${new_dependencies[@]}" | sort -u)); [[ debug -eq 1 ]] && echo "new_dependencies (post-sorting) ${new_dependencies[@]}" done # Some packages don't exist ('provides' ones such as 'sh' and also the 'no packages' identifier 'None') # Allowing them to make it this far is a bit quicker than filtering them earlier on. dependencies=() for package in ${new_dependencies[@]}; do pacman -Qi ${package} > /dev/null 2>&1 && dependencies+=("${package}") done [[ debug -eq 1 ]] && echo "num recursively dependent packages is ${#dependencies[@]}" # Now grep for the filename match. declare -a matching_files for package in ${dependencies[@]}; do matching_files+=($(pacman -Ql ${package} | cut -d' ' -f2 | grep -E "${regex}")) done matching_files=($(printf "%s\n" "${matching_files[@]}" | sort -u)); if [ "${outfile}" = "-" -o -z "${outfile}" ]; then echo ${matching_files[@]} | tr " " "\n" else echo ${matching_files[@]} | tr " " "\n" > "${outfile}" fi exit 0