68 lines
1.4 KiB
Bash
Executable File
68 lines
1.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT="."
|
|
declare -a SKIP_DIRS=()
|
|
declare -a PATTERNS=()
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $0 [-r root_dir] [-s dir_to_skip]... -p pattern ...
|
|
|
|
Options:
|
|
-r DIR Root directory (default: .)
|
|
-s DIR Directory name to skip (can repeat)
|
|
-p PATTERN File pattern (e.g. '*.md', '*.txt') (required, can repeat)
|
|
|
|
Example:
|
|
$0 -p '*.md'
|
|
$0 -r src -s node_modules -s .git -p '*.md' -p '*.txt'
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
while getopts ":r:s:p:" opt; do
|
|
case "$opt" in
|
|
r) ROOT="$OPTARG" ;;
|
|
s) SKIP_DIRS+=("$OPTARG") ;;
|
|
p) PATTERNS+=("$OPTARG") ;;
|
|
*) usage ;;
|
|
esac
|
|
done
|
|
|
|
shift $((OPTIND - 1))
|
|
|
|
# Require at least one pattern
|
|
(( ${#PATTERNS[@]} > 0 )) || usage
|
|
|
|
# Build prune expression
|
|
PRUNE_EXPR=()
|
|
if (( ${#SKIP_DIRS[@]} > 0 )); then
|
|
PRUNE_EXPR+=( \( )
|
|
for i in "${!SKIP_DIRS[@]}"; do
|
|
PRUNE_EXPR+=( -type d -name "${SKIP_DIRS[$i]}" -prune )
|
|
[[ $i -lt $((${#SKIP_DIRS[@]} - 1)) ]] && PRUNE_EXPR+=( -o )
|
|
done
|
|
PRUNE_EXPR+=( \) -o )
|
|
fi
|
|
|
|
# Build pattern expression
|
|
PATTERN_EXPR=( \( )
|
|
for i in "${!PATTERNS[@]}"; do
|
|
PATTERN_EXPR+=( -name "${PATTERNS[$i]}" )
|
|
[[ $i -lt $((${#PATTERNS[@]} - 1)) ]] && PATTERN_EXPR+=( -o )
|
|
done
|
|
PATTERN_EXPR+=( \) )
|
|
|
|
# Execute
|
|
find "$ROOT" \
|
|
"${PRUNE_EXPR[@]}" \
|
|
-type f \
|
|
"${PATTERN_EXPR[@]}" \
|
|
-print0 |
|
|
while IFS= read -r -d '' file; do
|
|
printf "\n===== %s =====\n" "$file"
|
|
cat "$file"
|
|
done
|
|
|