#!/bin/bash function lines_2_str () { [[ ! -f "$1" ]] && return 1 local str='' # echo the lines: $lines >&2 # lines="$(cat "$1")" while read line; do [[ "$line" =~ ^[[:space:]]*# ]] && continue # echo line: "${line}" >&2 str="$str ${line}" # echo str: $str >&2 done < $1 # for line in $lines ; do # str+='"'$line'" ' # done echo $str # set +o noglob return 0 } function super_find () { # echo super_find $@ >&2 # USAGE # all option arguments that contain globs/wildcards must be quoted to avoid expansion # f sets path and file excludes from a supplied file path # all lines ending in / will be treated as directory names to ignore, otherwise files # p option explictly excludes paths(directories) # d option sets the directory depth which is current directy by default, 0 is all # x excitly excludes file globs as a string # n inclucdes only file globs otherwise it's all except .files # if no directory is given it will attempt to source the present working directory # example: # source_dir -p "archive" -x '"*.off" "*.md"' -d 0 # $DIR/$SUBDIR declare OPTION declare OPTARG declare OPTIND local EXCLUDE_FILE local PATHS local NAMES local ENAMES local DEPTH=1 local VERBOSE=0 while getopts 'p:d:e:n:f:' OPTION; do case "$OPTION" in f) EXCLUDE_FILE=$OPTARG # echo EXCLUDE FILE $EXCLUDE_FILE >&2 ;; p) # PATHS=("$OPTARG") IFS=',' read -r -a PATHS <<< "$OPTARG" # echo EXCLUDING THESE PATHS ${PATHS[*]} ;; e) IFS=',' read -r -a ENAMES <<< "${OPTARG}" # echo EXCLUDING THESE FILE NAMES ${ENAMES[*]} ;; n) # NAMES=("$OPTARG") IFS=',' read -r -a NAMES <<< "${OPTARG}" # echo INCLUDING ONLY THESE FILE NAMES ${NAMES[*]} ;; d) DEPTH=$OPTARG # echo "SOURCING TO DEPTH (0=any)" "$DEPTH" ;; *) echo unknown option $OPTION ;; esac done shift $(( OPTIND - 1 )) local DIR DIR="$*" if [ ! "$DIR" ]; then if [ -v PS1 ]; then echo no directory to source provided echo sourcing present working directory $(pwd) read -p "Do you want to continue? " -n 1 -r [[ $REPLY =~ ^[Yy]$ ]] && DIR=$(pwd) || return 1 else return 1 fi fi [ ! -d "$DIR" ] && echo " directory $DIR does not exist, aborting" && return 1 # echo dir $DIR local FIND FIND="find $DIR" FIND+=$([ ! $DEPTH == 0 ] && echo " -maxdepth $DEPTH ") # ignore all .name and .path by default FIND+=" -type f ! -path \"*/.*/*\" ! -name \".*\" " local name local path if [[ -f $EXCLUDE_FILE ]]; then local ignores=$(lines_2_str "$EXCLUDE_FILE") # echo ignores: $ignores >&2 for exclude in $ignores ; do # echo exclude: ${exclude} >&2 [[ "$exclude" == */ ]] && PATHS+=("${exclude::-1}") || ENAMES+=("$exclude") done fi # echo paths ${PATHS[@]} >&2 # echo exclude names ${ENAMES[@]} >&2 if [[ ${PATHS[0]} ]]; then for path in ${PATHS[@]}; do # echo excluding $path FIND+=$(echo ' ! -path "*/'$path'/*"') done fi if [[ ${ENAMES[0]} ]]; then for name in ${ENAMES[@]}; do # echo excluding name $name FIND+=$(echo ' ! -name "'${name}'"') done fi if [[ ${NAMES[0]} ]]; then for name in ${NAMES[@]}; do # echo only finding $name FIND+=$(echo " -name ${name}") done fi # echo # echo find dir: $DIR >&2 # echo find command: $FIND >&2 local FILES FILES=$(eval $FIND | sort) echo $FILES return 0 } source_dir () { # echo passed: $* local FILES FILES=$(super_find "$@") [[ $? -ne 0 ]] && return 1 for f in $FILES; do # echo sourcing: $f source "$f" done }