Suppose I have defined an array, like this:
DIR=(A B Supercalifragilistic)
and I need to invoke the script as
./script A B Supercalifragilistic
where the arguments are processed by internal functions func1()
and func2()
. Is there a way to make an alias (or anything, however it's called) S
for Supercalifragilistic
so that when I invoke:
./script A B S
the internal functions will process/interpret S
as Supercalifragilistic
?
Thank you in advance.
[edit]
I should add that the script is invoked via terminal, not inside a script, and the arguments A B Supercalifragilistic
, or (hopefully) S
, are passed on to the script in the terminal. I'm sorry for the confusion.
[edit2]
The script is here: Bash script: if any argument is "N" then function has extra options , in the answer below. What it does is explained in the OP there, below the script. Finally, instead of DIR=(A B C D E F)
it's DIR=(A B Clarification D E F)
(it's just an example) and the folder Clarification
is the only one in a different path than the rest. I hope it's more clear now, if not, please tell me.
[final edit, I hope]
I think I can shout "Evrika!". Your word "hardcoded" made me realize I have to modify the script anytime a new folder gets added/deleted, so I thought of making the array dynamic, as in
./script a b "d e" g
results in array=(a b "d e" g)
but also that it should replace the long paths with some short ones (Clarification >> C
), so I made this test script based on also the answers here:
#!/bin/bash
array=()
for i in "$@"
do
if [[ "$i" == C ]]
then
array+=("Clarification")
else
array+=("$i")
fi
done
echo ${array[*]}
echo
for i in $(seq 0 $(( $# - 1 )))
do
echo ${array["$i"]}
done
and this is what it shows at command prompt:
$ ./x.sh abc C "d f" e
abc Clarification d f e
abc
Clarification
d f
e
I think now I can finally make the script to do what I want. Thank you, all, for the answers.
I really have no idea what you exactly want to achieve! But I had a look at the script you linked in your last edit. Since you have a hard-coded array you might as well instead use an associative array:
declare -A dir_h
dir_h["A"]=A
dir_h["B"]=B
dir_h["C"]=../path/Clarification
dir_h["D"]=D
dir_h["E"]=E
to loop on the keys of dir_h
, i.e., on A B C D E
:
for k in "${!dir_h[@]}"; do
echo "$k => ${dir_h[$k]}"
done
Try it, this might help you with your "alias" problem (or not).
Here's your script from your other post, using this technique and in a more consistent and readable form (note: I haven't tried it, there might be some minor typos, let me know if it's the case):
#!/bin/bash
# ./test.sh = 1. searches for existing archives
# 1.a. if they exist, it backups them into BKP/.
# 1.b. if not, displays a message
# 2. archives all the directories in the array list
# ./test.sh N = 1. deletes all the folder's archives existent and
# specified in the array list
# 2. archives all the directories in the array list
# ./test.sh {A..F} = 1. searches for existing archives from arguments
# 1.a. if they exist, it backups them into BKP/.
# 1.b. if not, displays a message
# 2. archives all the directories passed as arguments
# ./test.sh {A..F} N = 1. deletes all the archives matching $argument.zip
# 2. archives all the directories passed as arguments
# The directories to be backed-up/archived, all in the current (script's) path
# except "C", on a different path
declare -A dir_h
dir_h["A"]=A
dir_h["B"]=B
dir_h["C"]=../path/Clarification
dir_h["D"]=D
dir_h["E"]=E
dir_h["F"]=F
declare -A nope_h
nope_h["A"]=bogus
nope_h["B"]=bogus
nope_h["C"]=nope
nope_h["D"]=bogus
nope_h["E"]=bogus
nope_h["F"]=bogus
die() {
(($#)) && printf >&2 "%s\n" "$@"
exit 1
}
bak() {
if [[ "$1" != N ]]; then
# Check that arg is in dir list:
[[ -n ${dir_h["$1"]} ]] || die "Error in bak: argument \`$1' not handled"
if [[ -f $1.zip ]]; then
mv -vi "$1.zip" "BKP/$1.zip_$(date +"%H-%M")" || die
else
echo "$(tput setaf 1) no $1.zip$(tput sgr0)"
fi
fi
}
# The archive function, if any argument is "N", processing it is omitted. Folder
# "C" has special treatment
archive() {
if [[ $1 != N ]]; then
7z a -mx=9 "$1.zip" "${dir_h["$1"]}" -r -x\!"$1/${nope_h["$1"]}" || die
fi
}
# Let's check once for all whether N is in the arg list
foundN=0
for a in "$@"; do [[ $a = N ]] && foundN=1 && break; done
if (($#==0)); then
# case #1: no arguments
for d in "${!dir_h[@]}"; do
echo "$(tput setaf 2) backup$(tput sgr0)"
bak "$d"
archive "$d"
done
elif (($#==1)) && ((foundN)); then
# case #2: one argument, "N"
for d in "${!dir_h[@]}"; do
echo "$(tput setaf 1) no backup needed, removing$(tput sgr0)"
rm -v "$d".zip || die
archive "$d"
done
elif (($#>1)) && ((foundN)); then
# case #3: folders as arguments with "N"
for f in "$@"; do
if [[ $f != N ]]; then
echo "$(tput setaf 1) no backup needed, removing$(tput sgr0)"
rm -v "$f.zip" || die
fi
archive "$f"
done
else
for f in "$@"; do
echo "$(tput setaf 2) backup$(tput sgr0)"
bak "$f"
archive "$f"
done
fi
From this you can do a lot, and have pretty much infinite "alias" handling possibilities.
No need to use an alias. You could try something like :
$ cat test.sh
#!/bin/bash
declare -a args
for arg in "$@"; do
[[ $arg = "S" ]] && arg="Supercalifragilistic"
args+=( "$arg" )
done
for arg in "${args[@]}"; do
echo "$arg"
done
$ ./test.sh a b S e
a
b
Supercalifragilistic
e
You don't need alias here. Just set variable S
to your string:
S=Supercalifragilistic
and then use:
./script A B "$S"
OR else call your script directly using array:
./script ${DIR[@]}
PS: It is not a good habit to use all caps variable names in shell and you can accidentally overwrite PATH
variable some day.
You can do this:
processed_directories=()
for dir in "${directories[@]}"
do
if [ "$dir" = 'S' ]
then
dir='Supercalifragilistic'
fi
processed_directories+=("$dir")
done
It'll replace the value "S" with "Supercalifragilistic" anywhere in the array.