Skip to content

Commit

Permalink
'util-hdx.sh' updated
Browse files Browse the repository at this point in the history
  • Loading branch information
accetto committed May 25, 2019
1 parent bd94b3d commit 821c51b
Showing 1 changed file with 176 additions and 67 deletions.
243 changes: 176 additions & 67 deletions util-hdx.sh
Original file line number Diff line number Diff line change
@@ -1,69 +1,178 @@
#!/usr/bin/env bash
### Displays the file head and executes the chosen line, removing the first occurrence of '#' first.
### Providing NUMBER from the interval [1..9] skips the interaction and executes the given line directly.

fn_exec_header_line() {
local readonly me="util-hdx"
local arg1="$1"
local number=$2
local line=""

if [[ $# -eq 0 ]] ; then
echo "Displays the file head and executes the chosen line, removing the first occurrence of '#' first."
echo "Providing NUMBER from the interval [1..9] skips the interaction and executes the given line directly."
echo "usage: $me FILE [NUMBER]"
return 0
fi

if [ ! -f "$arg1" ] ; then echo "File [$arg1] not found!" ; return -1 ; fi
if [ $# -ge 2 ] ; then
if [[ $number -lt 1 || $number -gt 9 ]] ; then
echo "break"
echo "NUMBER must be from the interval [1..9]!"
return -1
fi
fi

if [ $# = 1 ] ; then

# output the header numbering the lines
head $arg1 | cat -n

read -rp $'Which line to execute? [1..9] ' -n1 key
if [[ "$key" = '' || "$key" -lt "1" || "$key" -gt "9" ]] ; then
# Space pressed, do something
# echo [$key] is empty when SPACE is pressed # uncomment to trace

echo "break"
echo "The NUMBER must be from the interval [1..9]!"
return 0
else
number=$key
fi
echo
fi

# get the command line and replace the first '#' by space
line=$(tail -n +$number $arg1 | head -n 1)
line=${line/'#'/}

if [ $# = 1 ] ; then

# display the chosen line
echo "$line"

read -rp $'Execute the line above? (y) ' -n1 key
if [ "$key" != "y" ] ; then
echo "break by user"
return 0
fi
echo
fi

echo

# execute the chosen line
($line)
#!/bin/bash
### @accetto (https://github.com/accetto) (https://hub.docker.com/u/accetto/)

# ARG_OPTIONAL_SINGLE([lines],[n],[Number of header lines to display],[10])
# ARG_POSITIONAL_SINGLE([file],[File containing the commands])
# ARG_POSITIONAL_SINGLE([line],[Number of the line to execute],[0])
# ARG_VERSION([echo $0 v19.05.25])
# ARG_HELP([Displays the file head and executes the chosen line, removing the first occurrence of '#' and trimming it from the left first.\nProviding the line number argument skips the interaction and executes the given line directly.])
# ARG_OPTIONAL_BOOLEAN([echo],[],[Just print the command line to be executed])
# ARGBASH_SET_INDENT([ ])
# ARGBASH_GO()
# needed because of Argbash --> m4_ignore([
### START OF CODE GENERATED BY Argbash v2.8.0 one line above ###
# Argbash is a bash code generator used to get arguments parsing right.
# Argbash is FREE SOFTWARE, see https://argbash.io for more info


die()
{
local _ret=$2
test -n "$_ret" || _ret=1
test "$_PRINT_HELP" = yes && print_help >&2
echo "$1" >&2
exit ${_ret}
}


begins_with_short_option()
{
local first_option all_short_options='nvh'
first_option="${1:0:1}"
test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
}

# THE DEFAULTS INITIALIZATION - POSITIONALS
_positionals=()
_arg_line="0"
# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_lines="10"
_arg_echo="off"


print_help()
{
printf '%s\n' "Displays the file head and executes the chosen line, removing the first occurrence of '#' and trimming it from the left first.
Providing the line number argument skips the interaction and executes the given line directly."
printf 'Usage: %s [-n|--lines <arg>] [-v|--version] [-h|--help] [--(no-)echo] <file> [<line>]\n' "$0"
printf '\t%s\n' "<file>: File containing the commands"
printf '\t%s\n' "<line>: Number of the line to execute (default: '0')"
printf '\t%s\n' "-n, --lines: Number of header lines to display (default: '10')"
printf '\t%s\n' "-v, --version: Prints version"
printf '\t%s\n' "-h, --help: Prints help"
printf '\t%s\n' "--echo, --no-echo: Just print the command line to be executed (off by default)"
}


parse_commandline()
{
_positionals_count=0
while test $# -gt 0
do
_key="$1"
case "$_key" in
-n|--lines)
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
_arg_lines="$2"
shift
;;
--lines=*)
_arg_lines="${_key##--lines=}"
;;
-n*)
_arg_lines="${_key##-n}"
;;
-v|--version)
echo $0 v19.05.25
exit 0
;;
-v*)
echo $0 v19.05.25
exit 0
;;
-h|--help)
print_help
exit 0
;;
-h*)
print_help
exit 0
;;
--no-echo|--echo)
_arg_echo="on"
test "${1:0:5}" = "--no-" && _arg_echo="off"
;;
*)
_last_positional="$1"
_positionals+=("$_last_positional")
_positionals_count=$((_positionals_count + 1))
;;
esac
shift
done
}


handle_passed_args_count()
{
local _required_args_string="'file'"
test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require between 1 and 2 (namely: $_required_args_string), but got only ${_positionals_count}." 1
test "${_positionals_count}" -le 2 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect between 1 and 2 (namely: $_required_args_string), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1
}

fn_exec_header_line "$@"

assign_positional_args()
{
local _positional_name _shift_for=$1
_positional_names="_arg_file _arg_line "

shift "$_shift_for"
for _positional_name in ${_positional_names}
do
test $# -gt 0 || break
eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1
shift
done
}

parse_commandline "$@"
handle_passed_args_count
assign_positional_args 1 "${_positionals[@]}"

# OTHER STUFF GENERATED BY Argbash

### END OF CODE GENERATED BY Argbash (sortof) ### ])
# [ <-- needed because of Argbash

_cmd=""
_input=""
_key=''
_line=$_arg_line
_size=10

[[ ! -f "$_arg_file" ]] && die "FAILED: File \"$_arg_file\" not found!"

_size=$(wc -l < "$_arg_file")
[[ $_size -gt $_arg_lines ]] && _size=$_arg_lines

if [[ $_line -le 0 ]] ; then
### output the header numbering the lines
head -n $_size "$_arg_file" | cat -n

### get the line number
read -rp $'Which line to execute? ' _input
_input=$(echo $_input | grep -E "^[0-9]+$")
[[ $_input ]] && _line=$_input || die "INTERRUPTED: Numeric input required!"
[[ $_line -lt 1 || $_line -gt $_size ]] && die "FAILED: The line number must be from the interval [1..$_size]!"
fi

### get the command line, remove the first '#' and trim it from the left
_cmd=$(sed "${_line}q;d" "$_arg_file")
_cmd=$(echo $_cmd | sed -r -e 's/^\s*#\s*//g')

### display the line to be executed
echo $_cmd

if [[ $_arg_line -eq 0 && "$_arg_echo" = "off" ]] ; then
### get user confirmation
read -rp $'Execute the line above? (y) ' -n1 _key
echo
[[ "${_key,,}" != "y" ]] && die "INTERRUPTED"
fi

if [[ "$_arg_echo" = "off" ]] ; then
### execute the chosen line
$_cmd
fi

# ] <-- needed because of Argbash

0 comments on commit 821c51b

Please sign in to comment.