Created
July 27, 2026 18:32
-
-
Save eliranmal/869cda4a5989cefd5a64d42c2a9300b9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| usage() { | |
| echo " | |
| USAGE | |
| ./sh-kebab.sh [path] [--dry-run] [--skip-dirs] [--copy-files] | |
| OVERVIEW | |
| this command renames all files in the current directory (or of the passed path), to the kebab-case naming convention. | |
| OPTIONS | |
| --dry-run | |
| only print out file names, without renaming any files on the system. | |
| --skip-dirs | |
| avoid renaming directories. | |
| --copy-files | |
| make file copies with kebab-cased names, instead of overwriting existing files. | |
| " | |
| } | |
| main() { | |
| local temp_dir | |
| local work_dir="$( pwd -P )" | |
| temp_dir="$(create_temp_dir)" | |
| cleanup_dir_on_exit "$temp_dir" | |
| greet_on_exit | |
| greet | |
| cmd_rename_files "$work_dir" "$temp_dir" "$@" | |
| } | |
| cmd_rename_files() { | |
| local is_dry_run | |
| local file | |
| local file_kebab | |
| local work_dir="$1" | |
| local temp_dir="$2" | |
| if is_dry_run "$@"; then | |
| log_ln 'listing file names in ['"$work_dir"']' | |
| else | |
| log_ln 'updating file names in ['"$work_dir"']' | |
| fi | |
| if is_dry_run "$@" || confirm_overwrite; then | |
| for path in "$work_dir"/*; do | |
| if should_skip_dirs "$@" && [[ -d "$path" ]]; then | |
| continue | |
| fi | |
| file="$(basename "$path")" | |
| file_kebab="$(kebabify "$file")" | |
| if is_dry_run "$@"; then | |
| log_file_data "$file" "$file_kebab" | |
| else | |
| if should_copy_files "$@"; then | |
| log 'copying...' | |
| log "source: $path" | |
| # log "dest: $(dirname "$path")/$file_kebab" | |
| # cp -pvR "$path" "$(dirname "$path")/sh-kebab-copy/$file_kebab" | |
| else | |
| log 'renaming...' | |
| # mv -- "$f" "${f%.backup}" | |
| fi | |
| fi | |
| done | |
| fi | |
| } | |
| has_param() { | |
| local term="$1" | |
| shift | |
| for arg; do | |
| if [[ $arg == "$term" ]]; then | |
| return 0 | |
| fi | |
| done | |
| return 1 | |
| } | |
| is_dry_run() { | |
| has_param '--dry-run' "$@" | |
| } | |
| should_skip_dirs() { | |
| has_param '--skip-dirs' "$@" | |
| } | |
| should_copy_files() { | |
| has_param '--copy-files' "$@" | |
| } | |
| confirm_overwrite() { | |
| prompt_confirm 'this will overwrite any existing files.' | |
| } | |
| log_file_data() { | |
| local file="$1" | |
| local file_kebab="$2" | |
| log "$file --> $file_kebab" | |
| if ! validateFilename "$file_kebab"; then | |
| log 'file name is invalid!' | |
| fi | |
| } | |
| kebabify() { | |
| echo "$1" | fill_with_dashes | camel_case_to_kebab_case | |
| } | |
| fill_with_dashes() { | |
| local term="$(cat -)" | |
| term="${term//_/-}" | |
| term="${term//[[:blank:]]/-}" | |
| # term="${term//[[:upper:]]+/\%}" | |
| echo "$term" | |
| } | |
| camel_case_to_kebab_case() { | |
| # - match uppercase letters that are not prefixed by a dash or another uppercase letter | |
| # - prefix them with dashes | |
| # - convert all uppercase letters into lowercase | |
| cat - | sed -E 's/([^-[[:upper:]]])([[:upper:]])/\1-\2/g;s/^-//' | tr '[:upper:]' '[:lower:]' | |
| # cat - | sed -E 's/[[:upper:]]/-&/g;s/^-//' | tr '[:upper:]' '[:lower:]' | |
| } | |
| # a simple check to ensure no spaces or underscores remain in the filename | |
| validateFilename() { | |
| ! [[ $1 =~ [[:blank:]]|_ ]] | |
| } | |
| create_temp_dir() { | |
| mktemp -d 2>/dev/null || mktemp -d -t 'sh-kebab' | |
| } | |
| cleanup_dir_on_exit() { | |
| trap 'rm -rf '"$@"' >/dev/null 2>&1' EXIT | |
| } | |
| greet() { | |
| log | |
| log_ln 'hi :)' | |
| } | |
| greet_on_exit() { | |
| trap 'log ; log_ln "bye bye!"' EXIT | |
| } | |
| prompt_confirm() { | |
| local message="$1" | |
| read -p "$(log "> $message continue? (y/n) ")" -r | |
| [[ $REPLY =~ ^[Yy]$ ]] | |
| } | |
| log() { | |
| echo " $1" | |
| } | |
| log_ln() { | |
| echo "$(log "$1") | |
| " | |
| } | |
| main "$@" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment