shell-base/modules/utility/file.lib

280 lines
6.8 KiB
Bash

#!/bin/bash
# export BASH_DEBUG=true
module_load debug
module_load iecho
isFile() {
if [[ -f $1 ]]
then
echo "true"
return 0
else
return 1
fi
}
#TODO
# env_file_pretty () {
# }
# https://www.baeldung.com/linux/envsubst-command
env_subs_file () {
module_load helpers
local input; local fenv; local all
[[ $1 == "-a" ]] && all=true && shift 1
input=$1
fenv=$2
[[ ! $input ]] && iecho "nothing was passed to merge with environment" && return 1
[[ -f "$input" ]] && input=$(cat "$input")
[[ ! $(echo $input | grep -F "$") ]] && iecho "nothing to merge in $1" && return 2
if [[ ($2 && ! -f $2) ]]; then
iecho "no enviroment file at $2" && return 3
else
# [[ $all ]] && export_file $fenv && unset fenv
if [[ $all ]]; then
fenv="/tmp/$USER/_tenvf"
# put quotes around values to avoid issues
env | sed 's/\(=[[:blank:]]*\)\(.*\)/\1"\2"/' > $fenv
cat $2 | sed 's/\(=[[:blank:]]*\)\(.*\)/\1"\2"/' | sed 's/\s*=\s*/=/g'
return
cat "$2" | sed 's/\(=[[:blank:]]*\)\(.*\)/\1"\2"/' >> $fenv
fi
fi
if [[ $fenv ]]; then
(set -a;source "$fenv" ;set +a; echo -e "$input" | envsubst "$(printf '${%s} ' $(cat "$fenv" | cut -d'=' -f1) )")
else
echo -e "$input" | envsubst "$(printf '${%s} ' $(env | cut -d'=' -f1) )"
fi
[[ $all ]] && rm -f $fenv
# [[ $all ]] && unset_file $2
}
# shift 1
# input=$1
# set -a;. $2 ;set +a;
# echo env file is now $2
# fi
build_file () {
# local file
# echo build file $1 $2
# todo merge no cr
[[ $1 == "-f" ]] && file=true && shift 1
[[ -f "$2" ]] || { iecho "output file $2 does not exist"; return 1; }
if [[ -f "$1" ]]; then
# echo adding file $1 to $2
[[ $file ]] && echo -e "\n####### ADDED $1 ########" >> $2
# remove comment lines, remove blank last line
cat "$1" | sed '/^\s*#/d' | sed '/^$/{:a;N;s/\n$//;ta}' >> $2
[[ ! $file ]] && echo -e "\n" >> $2
else iecho "no such file $1 to append to $2"
fi
}
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
}
# find, superceeds find use `command find` to get the super
function _find () {
# 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
local EXCLUDE_FILE
local PATHS
local NAMES
local ENAMES
local DEPTH=1
local HIDDEN
declare OPTION
declare OPTARG
declare OPTIND
while getopts 't:p:d:e:n:f:h' OPTION; do
case "$OPTION" in
t)
TYPE=$OPTARG
# echo "TYPE $TYPE"
;;
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}"
# NAMES=$OPTARG
;;
d)
DEPTH=$OPTARG
# echo "SOURCING TO DEPTH (0=any)" "$DEPTH"
;;
h)
HIDDEN=true
# 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 provided to search
echo searching 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="command find $DIR"
FIND+=$([ ! $DEPTH == 0 ] && echo " -maxdepth $DEPTH ")
# FIND+=" -type $([ $TYPE ] && echo "$TYPE" || echo "f")"
TYPE=${TYPE:-f}
FIND+=" -type $TYPE "
# include HIDDEN files and directories IS FALSE BY DEFULT
[[ ! $HIDDEN ]] && FIND+="! -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
set -o noglob
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
debug excluding name "$name"
FIND+=$(echo ' ! -name '$name'')
done
fi
debug "INCLUDING ONLY THESE FILE NAMES ${NAMES[*]}"
if [[ ${NAMES[0]} ]]; then
for name in "${NAMES[@]}"; do
debug only finding $name
FIND+=$(echo " -name '${name}'")
done
fi
# if [[ $NAMES ]]; then
# debug names for find command $NAMES
# for name in $NAMES; do
# debug "xxonly finding '$name'"
# FIND+=$(set -o noglob;echo " -name '${name}'")
# done
# fi
# echo
# echo find dir: $DIR >&2
debug "find command: $FIND"
set +o noglob
local FILES
FILES=$(eval $FIND | sort)
[[ $FILES ]] && echo $FILES
return 0
}
source_dir () {
# echo passed: $*
debug function: source_dir
local FILES
FILES=$(_find "$@") # find function
# echo $FILES >&2
[[ $? -ne 0 ]] && return 1
for f in $FILES; do
# echo sourcing: $f >&2
source "$f"
done
}
prepend_file () {
# ----------------------------------------------------------------------------------------------------------------------
# usage prepend_file <somefile> <anotherfile>
# ----------------------------------------------------------------------------------------------------------------------
# Prepend the contents of <somefile> [$1], to <anotherfile> [$2], leaving the result in <anotherfile> [$2].
# insert a newline at the end of <somefile> [$1] if necessary
# ----------------------------------------------------------------------------------------------------------------------
# check # echo $1 $2
[[ -f $1 ]] || return 1
[[ -f $2 ]] || return 2
# init
tmp_fn=$( mktemp -t TEMP_FILE_prepend.XXXXXXXX )
chmod 600 "$tmp_fn"
\cp $1 $tmp_fn
sed -i '$a\' $tmp_fn
cat $2 >> $tmp_fn
\mv "$tmp_fn" "$2"
# cleanup
rm -f "$tmp_fn"
return 0
# [End]
}