2 Commits

Author SHA1 Message Date
fatalerrors
96d1dc695d added missing function in help 2026-04-01 15:28:12 +02:00
fatalerrors
c039ab6ea0 improved and modernised file functions 2026-04-01 15:27:45 +02:00
2 changed files with 153 additions and 81 deletions

View File

@@ -35,32 +35,85 @@
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# expandlist : treat wildcards in a file/directory list
# Usage: expandlist <item1 [item2 ... itemN]>
# Expand wildcards in a file/directory list and quote the results
# Usage: expandlist [options] <item1 [item2 ... itemN]>
expandlist()
{
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
printf "expandlist: Wraps a list of items in double quotes.\n\n"
printf "Usage: expandlist <item1 [item2 ... itemN]>\n\n"
local separator=" "
local PARSED
PARSED=$(getopt -o hs:n --long help,separator:,newline -n 'expandlist' -- "$@")
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"expandlist --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
while true; do
case "$1" in
-h|--help)
printf "expandlist: expand globs and wrap matched items in double quotes.\n\n"
printf "Usage: expandlist [options] <item1 [item2 ... itemN]>\n\n"
printf "Options:\n"
printf "\t-h, --help\t\tDisplay this help screen\n"
printf "\t-s, --separator SEP\tSet output separator (default: space)\n"
printf "\t-n, --newline\t\tUse a newline as separator\n"
return 0
;;
-s|--separator)
separator="$2"
shift 2
;;
-n|--newline)
separator=$'\n'
shift
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"expandlist --help\" to display usage."
return 1
;;
esac
done
local item="" result="" matched=0
shopt -s nullglob
for item in "$@"; do
local expanded=()
# True glob expansion when wildcards are present.
if [[ "$item" == *'*'* || "$item" == *'?'* || "$item" == *'['* ]]; then
expanded=( $item )
else
expanded=( "$item" )
fi
local result=""
for item in "$@"; do
for content in "$item"; do
result+="\"$content\" "
if [[ ${#expanded[@]} -eq 0 ]]; then
continue
fi
for content in "${expanded[@]}"; do
if (( matched )); then
result+="$separator"
fi
result+="\"$content\""
matched=1
done
done
echo $result
shopt -u nullglob
printf '%s\n' "$result"
}
export -f expandlist
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Clean a directory or a tree from temporary or backup files
# Clean a directory tree from temporary or backup files
# Usage: clean [options] [directory1] [...[directoryX]]
# Options:
# -h, --help: display help screen
@@ -85,7 +138,7 @@ clean()
while true; do
case "$1" in
-r|--recurs)
local recursive=1
recursive=1
shift
;;
-h|--help)
@@ -100,11 +153,11 @@ clean()
return 0
;;
-s|--shell)
local outshell=1
outshell=1
shift
;;
-f|--force)
local force=1
force=1
shift
;;
--)
@@ -114,6 +167,7 @@ clean()
*)
disp E "Invalid parameter, use \"clean --help\" to display options list"
return 1
;;
esac
done
@@ -121,21 +175,24 @@ clean()
local dirlist=("$@")
[[ ${#dirlist[@]} -eq 0 ]] && dirlist=(".")
local findopt=() rmopt
[[ ! $recursive ]] && findopt=(-maxdepth 1)
[[ ! $force ]] && rmopt="-i"
unset recursive force
local findopt=() rmopt=()
(( ! recursive )) && findopt=(-maxdepth 1)
(( ! force )) && rmopt=(-i)
for dir in $dirlist; do
find "$dir" "${findopt[@]}" -type f \( -name "*~" -o -name "#*#" -o -name "*.bak" -o -name ".~*#" \) -print0 | while IFS= read -r -d '' f; do
if [[ ! $outshell ]]; then
rm $rmopt $f
for dir in "${dirlist[@]}"; do
find "$dir" "${findopt[@]}" -type f \( -name "*~" -o -name "#*#" -o -name "*.bak" -o -name ".~*#" \) -print0 |
while IFS= read -r -d '' f; do
if (( outshell )); then
if (( ${#rmopt[@]} )); then
printf 'rm %s -- "%s"\n' "${rmopt[*]}" "$f"
else
echo "rm $rmopt $f"
printf 'rm -- "%s"\n' "$f"
fi
else
rm "${rmopt[@]}" -- "$f"
fi
done
done
unset outshell dirlist dellist findopt rmopt
}
export -f clean
# ------------------------------------------------------------------------------
@@ -168,7 +225,7 @@ export -f mcd
# ------------------------------------------------------------------------------
# Rename all files in current directory to replace spaces with _
# Rename files and directories to replace spaces with another character
# Usage: rmspc [options]
# Options:
# -h, --help: display help screen
@@ -178,8 +235,11 @@ export -f mcd
# -s, --shell: do nothing and display commands that would be executed
rmspc()
{
local lst=""
local recurs=0 verb=0 shell=0
local substchar="_" substchar_set=0
local mvopt=()
local PARSED
PARSED=$(getopt -o hr:c::vs --long help,recursive,subst-char::,verbose,shell -n 'rmspc' -- "$@")
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"rmspc --help\" to display usage."
@@ -203,27 +263,20 @@ rmspc()
return 0
;;
-r|--recursive)
local recurs=1
recurs=1
shift
;;
-c|--subst-char)
# Handle optional argument for short/long options
case "$2" in
"")
substchar=""
;;
*)
substchar_set=1
substchar="$2"
;;
esac
shift 2
;;
-v|--verbose)
local verb=1
verb=1
shift
;;
-s|--shell)
local shell=1
shell=1
shift
;;
--)
@@ -232,49 +285,58 @@ rmspc()
;;
*)
disp E "Invalid parameter, use \"rmspc --help\" to display options list"
echo
return 1
;;
esac
done
[[ ! $substchar ]] && substchar="_"
[[ $substchar == "none" ]] && local substchar=""
[[ $verb ]] && local mvopt="-v"
[[ "$substchar" == "none" ]] && substchar=""
(( verb )) && mvopt=(-v)
shopt -s nullglob
for f in *; do
[[ $recurs ]] && [[ -d "$f" ]] && (
[[ $verb ]] && disp I "Entering directory $(pwd)/$f ..."
if (( recurs )) && [[ -d "$f" ]]; then
(
local lastdir=$f
pushd "$f" >/dev/null
rmspc ${recurs:+-r} ${substchar:+-c "$substchar"} ${verb:+-v} ${shell:+-s}
popd >/dev/null
[[ $verb ]] && disp I "Leaving directory $(pwd)/$lastdir"
unset lastdir
(( verb )) && disp I "Entering directory $(pwd)/$f ..."
pushd "$f" >/dev/null || exit 1
if (( substchar_set )); then
rmspc ${recurs:+-r} -c "$substchar" ${verb:+-v} ${shell:+-s}
else
rmspc ${recurs:+-r} ${verb:+-v} ${shell:+-s}
fi
popd >/dev/null || exit 1
(( verb )) && disp I "Leaving directory $(pwd)/$lastdir"
)
fi
if [[ "$f" == *" "* ]]; then
local newf="${f// /${substchar}}"
[[ "$f" == "$newf" ]] && continue # protection but should never happen
if [[ -n $shell ]]; then
echo "mv ${mvopt:+$mvopt }\"$f\" \"$newf\""
[[ "$f" == "$newf" ]] && continue
if (( shell )); then
if (( ${#mvopt[@]} )); then
printf 'mv %s -- "%s" "%s"\n' "${mvopt[*]}" "$f" "$newf"
else
mv ${mvopt:+$mvopt} "$f" "$newf" || {
printf 'mv -- "%s" "%s"\n' "$f" "$newf"
fi
else
mv "${mvopt[@]}" -- "$f" "$newf" || {
disp E "Failed renaming \"$f\" to \"$newf\"."
continue
}
fi
fi
done
unset lst substchar verb shell newf command mvopt
shopt -u nullglob
}
export -f rmspc
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# display stats about a file structure
# Display statistics about a file tree
# Usage: file_stats [options] [path]
# Options:
# -H, --human Human readable sizes\n"
@@ -290,7 +352,7 @@ export -f rmspc
# --max [size] Maximum size (e.g., 100M)
file_stats()
{
local human=0 details=0 only_avg=0 only_med=0 only_count=0 only_total=0
local human=0 details=0 only_avg=0 only_med=0 only_count=0 only_total=0
local path="." show_all=1 ext_filter="" ext_list="" min_size="" max_size=""
local PARSED
@@ -387,12 +449,12 @@ local human=0 details=0 only_avg=0 only_med=0 only_count=0 only_total=0
# Prepare find filters
local find_cmd=(find "$path" -type f)
# Extension simple
# Single extension filter
if [[ -n "$ext_filter" ]]; then
find_cmd+=(-iname "*.$ext_filter")
fi
# Extension liste
# Extension list filter
if [[ -n "$ext_list" ]]; then
IFS=',' read -ra exts <<< "$ext_list"
find_cmd+=('(')
@@ -403,7 +465,7 @@ local human=0 details=0 only_avg=0 only_med=0 only_count=0 only_total=0
find_cmd+=(')')
fi
# Taille min/max (à évaluer en octets)
# Minimum/maximum size filters (evaluated in bytes)
if [[ -n "$min_size" ]]; then
find_cmd+=(-size +"$(numfmt --from=iec "$min_size")"c)
fi
@@ -411,7 +473,7 @@ local human=0 details=0 only_avg=0 only_med=0 only_count=0 only_total=0
find_cmd+=(-size -"$(( $(numfmt --from=iec "$max_size") + 1 ))"c)
fi
# Exécution
# Execution
"${find_cmd[@]}" -printf "%s\n" 2>/dev/null | sort -n | \
awk -v human="$human" -v details="$details" -v only_avg="$only_avg" \
-v only_med="$only_med" -v only_count="$only_count" \
@@ -512,10 +574,10 @@ export -f file_stats
# -l : limit : number of files to return (default is 10)
findbig()
{
local details=0 limit=10 no_change=0 one_fs=0
local details=0 limit=10 one_fs=0
local PARSED
PARSED=$(getopt -o hd:l:x --long help,details,one-fs,limit: -n 'findbig' -- "$@")
PARSED=$(getopt -o hdl:x --long help,details,limit:,one-fs -n 'findbig' -- "$@")
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"findbig --help\" to display usage."
return 1
@@ -538,14 +600,18 @@ findbig()
details=1
shift
;;
-n|--no-change)
no_change=1
shift
;;
-l|--limit)
limit="$2"
[[ "$limit" =~ ^[0-9]+$ ]] || {
disp E "Invalid limit: must be a positive integer."
return 1
}
shift 2
;;
-x|--one-fs)
one_fs=1
shift
;;
--)
shift
break
@@ -560,13 +626,16 @@ findbig()
local dir="${1:-.}"
# Prepare find arguments in an array for cleaner handling
local find_args=("-L" "$dir" "-type" "f")
(( one_fs )) && find_args+=("-xdev")
local find_args=(-L "$dir")
(( one_fs )) && find_args+=(-xdev)
find_args+=(-type f)
# Logic: find files, print size and path, sort numeric reverse, take N
if (( details )); then
find "${find_args[@]}" -printf "%s %p\n" 2>/dev/null | sort -rn | head -n "$limit" | while read -r size path; do
ls -ld "$path"
find "${find_args[@]}" -printf "%s %p\n" 2>/dev/null | sort -rn | head -n "$limit" |
while IFS= read -r line; do
local path="${line#* }"
ls -ld -- "$path"
done
else
find "${find_args[@]}" -printf "%s %p\n" 2>/dev/null | sort -rn | head -n "$limit"
@@ -586,7 +655,7 @@ export -f findbig
# --delete : delete empty files and display their paths
findzero()
{
local delete=0 details=0 one_fs=0 no_change=0
local delete=0 details=0 one_fs=0
local PARSED
# o: options, long: long equivalents
@@ -660,7 +729,7 @@ export -f findzero
# --delete : delete dead links and display their paths
finddead()
{
local delete=0 details=0 one_fs=0 no_change=0
local delete=0 details=0 one_fs=0
local PARSED
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'finddead' -- "$@")

View File

@@ -39,6 +39,8 @@
# Usage: help
help()
{
printf "${BIWhite}Welcome to your profile! Here is a list of available commands:${DEFAULTCOL}\n\n"
printf "check_updates\tCheck for new versions of profile\n"
printf "clean\t\tErase backup files\n"
printf "disp\t\tDisplay formatted info/warning/error/debug messages\n"
printf "dwl\t\tDownload a URL to a local file\n"
@@ -60,6 +62,7 @@ help()
printf "ppg\t\tDisplay process matching the given parameter\n"
printf "ppn\t\tDisplay process matching the exact process name given in parameter\n"
printf "ppu\t\tDisplay processes owned by the given user\n"
printf "profile_upgrade\tUpgrade profile to the latest version\n"
printf "rain\t\tLet the rain fall\n"
printf "rmhost\t\tRemove host (IP and/or DNS name) from current known_hosts\n"
printf "rmspc\t\tRemove spaces from file and directory names\n"