Pronounced any way you want.
Argus provides a KISS implementation of associative and indexed lists in any POSIX-compliant shell. Argus has a simple data structure, allowing you to manipulate and filter the lists using simple common shell tools.
Current status is under development, use with care.
First source argus:
source argus.sh
Creating an empty list is as simple as:
my_argus=''
Let us implement the following YAML object literal:
name: Argus Array
description:
type: Subspace telescope
operator: Starfleet
quadrant: alpha
energy_source: fusion reactor
status:
reactor:
- true
- true
- true
- false
add_value my_argus 'name' 'Argus Array'
add_value my_argus 'description type' 'Subspace telescope'
add_value my_argus 'description operator' 'Starfleet'
add_value my_argus 'description quadrant' 'alpha'
add_value my_argus 'description energy_source' 'fusion reactor'
add_value my_argus 'status reactor' 'true'
add_value my_argus 'status reactor' 'true'
add_value my_argus 'status reactor' 'true'
add_value my_argus 'status reactor' 'false'
Here we define the CSV in a variable as an example:
dilithium_reserves='deneva,1337
io,521
elas,5147
remus,217'
while IFS=',' read key value; do
add_value my_argus "status dilithium_reserves $key" "$value"
done << EOF
$(printf '%s\n' "$dilithium_reserves")
EOF
Just write it to a file
get my_argus > my_argus
And restore from backup:
my_argus=$(cat my_argus)
Regular expressions are supported in all get
functions. The regular expression should not contain
(space), as that sign is used to separate keys.
get_value my_argus 'status reactor'
Stdout:
true
false
rm_key my_argus 'description operator'
Will remove the key operator
nested under description
and all it's content.
rm_at_key my_argus 'status reactor' '1'
Will remove the first element (true
) from reactor
nested under status
. Note that the first element is 1, not 0.
rm_value my_argus 'status reactor' 'false'
Will remove all reactors with status false. rmx_value
also supports regular expressions, so you could replace 'false'
with 'f.*'
for the same result.
For a complete list of function and their documentation/usage see
Use grep
, sed
, awk
etc.
Below are some examples:
get_value my_argus 'status reactor' | grep -cxF 'false'
In awk
the value is always located in $NF
.
get my_argus 'status reactor' | awk -v FS='\t' '{ if($NF == "true") { print } }'
Or using grep
:
get my_argus 'status reactor' | grep -E '\ttrue$'
get my_argus | awk -v FS='\t' '{ if ($2 ~ "operator" && $2 != $NF) { print }}'
The query in the example above could also been done using get
and with a regular expression: get my_argus '.+ operator'
Get systems where the dilithium reserves are low:
while IFS= read -r entry; do
reserves=$(get_value entry)
system=$(echo "$entry" | awk '{print $1}')
if test "$reserves" -lt 1000; then
printf 'system "%s" has dangerously low reserves of dilithium: %s\n' "$system" "$reserves"
fi
done << EOF
$(get_tail my_argus 'status dilithium_reserves')
EOF
For additional examples see
In most shells a pipeline spawn a new subshell, the common idiom to overcome this is to use here docs:
IFS= add_value my_argus 'description location' << EOF
$(printf 'Alpha Quadrant\n')
EOF
In shells that allow it, like zsh you could do:
printf 'Alpha Quadrant\n' | { add_value my_argus 'description location'; }
If you think Argus sounds interesting, and want to investigate more, take a look in the documentation