Merge pull request #4 from dylanaraps/better_desc

added examples
This commit is contained in:
Dylan Araps
2018-06-15 09:53:07 +10:00
committed by GitHub
3 changed files with 464 additions and 212 deletions

View File

@@ -4,5 +4,5 @@ os:
- linux
script:
- shellcheck -s bash --exclude=SC2034,SC2154 <(awk '/```sh/{f=1;next}/```/{f=0}f' README.md)
- shellcheck -s bash --exclude=SC2034,SC2154 <(awk '/```sh$/{f=1;next}/```/{f=0}f' README.md)
- ./test.sh

460
README.md
View File

@@ -104,6 +104,8 @@ scripts and not full blown utilities.
### Trim leading and trailing white-space from string.
**Example Function:**
```sh
trim_string() {
# Usage: trim_string " example string "
@@ -113,12 +115,26 @@ trim_string() {
}
```
**Example Usage:**
```shell
$ trim_string " Hello, World "
Hello, World
$ name=" John Black "
$ trim_string "$name"
John Black
```
### Trim all white-space from string and truncate spaces.
**Example Function:**
```sh
# shellcheck disable=SC2086,SC2048
trim_all() {
# Usage: trim " example string "
# Usage: trim_all " example string "
set -f
set -- $*
printf '%s\n' "$*"
@@ -126,6 +142,17 @@ trim_all() {
}
```
**Example Usage:**
```shell
$ trim_all " Hello, World "
Hello, World
$ name=" John Black is my name. "
$ trim_all "$name"
John Black is my name.
```
### Use REGEX on a string.
We can use the result of `bash`'s regex matching to create a simple `sed`
@@ -138,55 +165,68 @@ Stick to POSIX regex features if aiming for compatibility.
**NOTE**: This example only prints the first matching group. When using
multiple capture groups some modification will be needed.
**Example Function:**
```sh
regex() {
# Usage: regex "string" "regex"
[[ $1 =~ $2 ]] && printf '%s\n' "${BASH_REMATCH[1]}"
}
```
# Example:
# Trim leading white-space.
: regex ' hello' '^\s*(.*)'
**Example Usage:**
```shell
$ # Trim leading white-space.
$ regex ' hello' '^\s*(.*)'
hello
# Example script usage (Validate hex colors):
_() {
colors=(
"#FFFFFF"
"#000000"
"#CDEFDC"
"#12dlks"
"red"
)
$ # Validate a hex color.
$ regex "#FFFFFF" '^(#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3}))$'
#FFFFFF
for color in "${colors[@]}"; do
if [[ "$color" =~ ^(#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3}))$ ]]; then
$ # Validate a hex color (invalid).
$ regex "red" '^(#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3}))$'
# no output (invalid)
```
**Example Usage in script:**
```shell
is_hex_color() {
if [[ "$1" =~ ^(#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3}))$ ]]; then
printf '%s\n' "${BASH_REMATCH[1]}"
else
printf '%s\n' "error: $color is an invalid color."
printf '%s\n' "error: $1 is an invalid color."
return 1
fi
done
}
read -r color
is_hex_color "$color" || color="#FFFFFF"
# Do stuff.
```
### Split a string on a delimiter.
```sh
_() {
# To multiple variables.
```shell
string="1,2,3"
# To multiple variables.
IFS=, read -r var1 var2 var3 <<< "$string"
# To an array.
IFS=, read -ra vars <<< "$string"
}
```
### Change a string to lowercase.
**NOTE:** Requires `bash` 4+
**Example Function:**
```sh
lower() {
# Usage: lower "string"
@@ -194,10 +234,25 @@ lower() {
}
```
**Example Usage:**
```shell
$ lower "HELLO"
hello
$ lower "HeLlO"
hello
$ lower "hello"
hello
```
### Change a string to uppercase.
**NOTE:** Requires `bash` 4+
**Example Function:**
```sh
upper() {
# Usage: upper "string"
@@ -205,8 +260,23 @@ upper() {
}
```
**Example Usage:**
```shell
$ upper "hello"
HELLO
$ upper "HeLlO"
HELLO
$ upper "HELLO"
HELLO
```
### Trim quotes from a string.
**Example Function:**
```sh
trim_quotes() {
# Usage: trim_quotes "string"
@@ -215,42 +285,63 @@ trim_quotes() {
}
```
**Example Usage:**
```shell
$ var="'Hello', \"World\""
$ trim_quotes "$var"
Hello, World
```
### Strip all instances of pattern from string.
**Example Function:**
```sh
strip_all() {
# Usage: strip_all "string" "pattern"
printf '%s\n' "${1//$2}"
}
```
# Examples:
**Example Usage:**
# Output: "Th Qck Brwn Fx"
: strip_all "The Quick Brown Fox" "[aeiou]"
```shell
$ strip_all "The Quick Brown Fox" "[aeiou]"
Th Qck Brwn Fx
# Output: "TheQuickBrownFox"
: strip_all "The Quick Brown Fox" "[[:space:]]"
$ strip_all "The Quick Brown Fox" "[[:space:]]"
TheQuickBrownFox
$ strip_all "The Quick Brown Fox" "Quick "
The Brown Fox
```
### Strip first occurrence of pattern from string.
**Example Function:**
```sh
strip() {
# Usage: strip "string" "pattern"
printf '%s\n' "${1/$2}"
}
```
# Examples:
**Example Usage:**
# Output: "Th Quick Brown Fox"
: strip_all "The Quick Brown Fox" "[aeiou]"
```shell
$ strip "The Quick Brown Fox" "[aeiou]"
Th Quick Brown Fox
# Output: "TheQuick Brown Fox"
: strip_all "The Quick Brown Fox" "[[:space:]]"
$ strip "The Quick Brown Fox" "[[:space:]]"
TheQuick Brown Fox
```
### Strip pattern from start of string.
**Example Function:**
```sh
lstrip() {
# Usage: lstrip "string" "pattern"
@@ -258,8 +349,17 @@ lstrip() {
}
```
**Example Usage:**
```shell
$ lstrip "The Quick Brown Fox" "The "
Quick Brown Fox
```
### Strip pattern from end of string.
**Example Function:**
```sh
rstrip() {
# Usage: rstrip "string" "pattern"
@@ -267,12 +367,18 @@ rstrip() {
}
```
**Example Usage:**
```shell
$ rstrip "The Quick Brown Fox" " Fox"
The Quick Brown
```
## Variables
### Assign and access a variable using a variable.
```sh
_() {
```shell
hello_world="test"
# Create the variable name.
@@ -281,7 +387,6 @@ _() {
# Print the value of the variable name stored in 'hello_$var1'.
printf '%s\n' "${!var2}"
}
```
@@ -292,16 +397,34 @@ _() {
Enabling `extdebug` allows access to the `BASH_ARGV` array which stores
the current functions arguments in reverse.
**Example Function:**
```sh
reverse_array() {
# Usage: reverse_array "array"
# reverse_array 1 2 3 4 5 6
shopt -s extdebug
f()(printf '%s\n' "${BASH_ARGV[@]}"); f "$@"
shopt -u extdebug
}
```
**Example Usage:**
```shell
$ reverse_array 1 2 3 4 5
5
4
3
2
1
$ arr=(red blue green)
$ reverse_array "${arr[@]}"
green
blue
red
```
### Remove duplicate array elements.
Create a temporary associative array. When setting associative array
@@ -310,6 +433,8 @@ allows us to effectively remove array duplicates.
**NOTE:** Requires `bash` 4+
**Example Function:**
```sh
remove_array_dups() {
# Usage: remove_array_dups "array"
@@ -323,6 +448,23 @@ remove_array_dups() {
}
```
**Example Usage:**
```shell
$ remove_array_dups 1 1 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 5
1
2
3
4
5
$ arr=(red red green blue blue)
$ remove_array_dups "${arr[@]}"
red
green
blue
```
### Cycle through an array.
Each time the `printf` is called, the next array element is printed. When
@@ -360,24 +502,20 @@ cycle() {
Alternative to the `cat` command.
```sh
_() {
```shell
file_data="$(<"file")"
}
```
### Read a file to an array (*by line*).
Alternative to the `cat` command.
```sh
_() {
```shell
# Bash <4
IFS=$'\n' read -d "" -ra file_data < "file"
# Bash 4+
mapfile -t file_data < "file"
}
```
### Get the first N lines of a file.
@@ -386,6 +524,8 @@ Alternative to the `head` command.
**NOTE:** Requires `bash` 4+
**Example Function:**
```sh
head() {
# Usage: head "n" "file"
@@ -394,12 +534,25 @@ head() {
}
```
**Example Usage:**
```shell
$ head 2 ~/.bashrc
# Prompt
PS1='➜ '
$ head 1 ~/.bashrc
# Prompt
```
### Get the last N lines of a file.
Alternative to the `tail` command.
**NOTE:** Requires `bash` 4+
**Example Function:**
```sh
tail() {
# Usage: tail "n" "file"
@@ -408,12 +561,25 @@ tail() {
}
```
**Example Usage:**
```shell
$ tail 2 ~/.bashrc
# Enable tmux.
# [[ -z "$TMUX" ]] && exec tmux
$ tail 1 ~/.bashrc
# [[ -z "$TMUX" ]] && exec tmux
```
### Get the number of lines in a file.
Alternative to `wc -l`.
**NOTE:** Requires `bash` 4+
**Example Function:**
```sh
lines() {
# Usage lines "file"
@@ -422,12 +588,18 @@ lines() {
}
```
**Example Usage:**
```shell
$ lines ~/.bashrc
48
```
### Iterate over files.
Dont use `ls`.
```sh
_() {
```shell
# Greedy example.
for file in *; do
printf '%s\n' "$file"
@@ -449,7 +621,6 @@ _() {
printf '%s\n' "$file"
done
shopt -u globstar
}
```
### Count files or directories in directory.
@@ -457,6 +628,8 @@ _() {
This works by passing the output of the glob as function arguments. We
then count the arguments and print the number.
**Example Function:**
```sh
count() {
# Usage: count /path/to/dir/*
@@ -465,19 +638,33 @@ count() {
}
```
**Example Usage:**
```shell
# Count all files in dir.
$ count ~/Downloads/*
232
# Count all dirs in dir.
$ count ~/Downloads/*/
45
# Count all jpg files in dir.
$ count ~/Pictures/*.jpg
64
```
### Create an empty file.
Alternative to `touch`.
```sh
_() {
```shell
# Shortest.
:> file
# Longer alternatives:
echo -n > file
printf '' > file
}
```
## File Paths
@@ -486,6 +673,8 @@ _() {
Alternative to the `dirname` command.
**Example Function:**
```sh
dirname() {
# Usage: dirname "path"
@@ -493,10 +682,22 @@ dirname() {
}
```
**Example Usage:**
```shell
$ dirname ~/Pictures/Wallpapers/1.jpg
/home/black/Pictures/Wallpapers/
$ dirname ~/Pictures/Downloads/
/home/black/Pictures/
```
### Get the base-name of a file path.
Alternative to the `basename` command.
**Example Function:**
```sh
basename() {
# Usage: basename "path"
@@ -505,12 +706,22 @@ basename() {
}
```
**Example Usage:**
```shell
$ basename ~/Pictures/Wallpapers/1.jpg
1.jpg
$ basename ~/Pictures/Downloads/
Downloads
```
## Arithmetic
### Simpler syntax to set variables.
```sh
_() {
```shell
# Simple math
((var=1+2))
@@ -522,26 +733,25 @@ _() {
# Using variables
((var=var2*arr[2]))
}
```
### Ternary tests.
```sh
_() {
```shell
# Set the value of var to var2 if var2 is greater than var.
# var: variable to set.
# var2>var: Condition to test.
# ?var2: If the test succeeds.
# :var: If the test fails.
((var=var2>var?var2:var))
}
```
## Colors
### Convert a hex color to RGB.
**Example Function:**
```sh
hex_to_rgb() {
# Usage: hex_to_rgb "#FFFFFF"
@@ -553,8 +763,18 @@ hex_to_rgb() {
}
```
**Example Usage:**
```shell
$ hex_to_rgb "#FFFFFF"
255 255 255
```
### Convert an RGB color to hex.
**Example Function:**
```sh
rgb_to_hex() {
# Usage: rgb_to_hex "r" "g" "b"
@@ -562,6 +782,13 @@ rgb_to_hex() {
}
```
**Example Usage:**
```shell
$ rgb_to_hex "255" "255" "255"
#FFFFFF
```
## Information about the terminal
### Get the terminal size in lines and columns (*from a script*).
@@ -569,6 +796,8 @@ rgb_to_hex() {
This is handy when writing scripts in pure bash and `stty`/`tput` cant be
called.
**Example Function:**
```sh
get_term_size() {
# Usage: get_term_size
@@ -580,10 +809,20 @@ get_term_size() {
}
```
**Example Usage:**
```shell
# Output: LINES COLUMNS
$ get_term_size
15 55
```
### Get the terminal size in pixels.
**NOTE**: This does not work in some terminal emulators.
**Example Function:**
```sh
get_window_size() {
# Usage: get_window_size
@@ -593,10 +832,25 @@ get_window_size() {
}
```
**Example Usage:**
```shell
# Output: WIDTHxHEIGHT
$ get_window_size
1200x800
# Output (fail):
$ get_window_size
x
```
### Get the current cursor position.
This is useful when creating a TUI in pure bash.
**Example Function:**
```sh
get_cursor_pos() {
# Usage: get_cursor_pos
@@ -605,43 +859,45 @@ get_cursor_pos() {
}
```
**Example Usage:**
```shell
# Output: X Y
$ get_cursor_pos
1 8
```
## Code Golf
### Shorter `for` loop syntax.
```sh
_() {
```shell
# Tiny C Style.
for((;i++<10;)){ echo "$i";}
# Undocumented method.
# Note: This is commented to make shellcheck play nice.
# for i in {1..10};{ echo "$i";}
for i in {1..10};{ echo "$i";}
# Expansion.
for i in {1..10}; do echo "$i"; done
# C Style.
for((i=0;i<=10;i++)); do echo "$i"; done
}
```
### Shorter infinite loops.
```sh
_() {
```shell
# Normal method
while :; do echo hi; done
# Shorter
for((;;)){ echo hi;}
}
```
### Shorter function declaration.
```sh
_() {
```shell
# Normal method
f(){ echo hi;}
@@ -656,16 +912,13 @@ _() {
# Using tests, loops etc.
# NOTE: You can also use while, until, case, (()), [[]].
# NOTE: These are commented to make shellcheck play nice.
# f()if true; then echo "$1"; fi
# f()for i in "$@"; do echo "$i"; done
}
f()if true; then echo "$1"; fi
f()for i in "$@"; do echo "$i"; done
```
### Shorter `if` syntax.
```sh
_() {
```shell
# One line
[[ "$var" == hello ]] && echo hi || echo bye
[[ "$var" == hello ]] && { echo hi; echo there; } || echo bye
@@ -679,7 +932,6 @@ _() {
echo hi
# ...
}
}
```
### Simpler `case` statement to set variable.
@@ -689,8 +941,7 @@ statement. The `$_` variable stores the last argument of the last
successful command. `:` always succeeds so we can abuse it to store the
variable value.
```sh
_() {
```shell
# Example snippet from Neofetch.
case "$(uname)" in
"Linux" | "GNU"*)
@@ -713,7 +964,6 @@ _() {
# Finally, set the variable.
os="$_"
}
```
## Internal Variables
@@ -726,60 +976,60 @@ http://tldp.org/LDP/abs/html/internalvariables.html
### Get the location to the `bash` binary.
```sh
: "$BASH"
```shell
"$BASH"
```
### Get the version of the current running `bash` process.
```sh
```shell
# As a string.
: "$BASH_VERSION"
"$BASH_VERSION"
# As an array.
: "${BASH_VERSINFO[@]}"
"${BASH_VERSINFO[@]}"
```
### Open the user's preferred text editor.
```sh
: "$EDITOR" "$file"
```shell
"$EDITOR" "$file"
# NOTE: This variable may be empty, set a fallback value.
: "${EDITOR:-vi}" "$file"
"${EDITOR:-vi}" "$file"
```
### Get the name of the current function.
```sh
```shell
# Current function.
: "${FUNCNAME[0]}"
"${FUNCNAME[0]}"
# Parent function.
: "${FUNCNAME[1]}"
"${FUNCNAME[1]}"
# So on and so forth.
: "${FUNCNAME[2]}"
: "${FUNCNAME[3]}"
"${FUNCNAME[2]}"
"${FUNCNAME[3]}"
# All functions including parents.
: "${FUNCNAME[@]}"
"${FUNCNAME[@]}"
```
### Get the host-name of the system.
```sh
: "$HOSTNAME"
```shell
"$HOSTNAME"
# NOTE: This variable may be empty.
# Optionally set a fallback to the hostname command.
: "${HOSTNAME:-$(hostname)}"
"${HOSTNAME:-$(hostname)}"
```
### Get the architecture of the Operating System.
```sh
: "$HOSTTYPE"
```shell
"$HOSTTYPE"
```
### Get the name of the Operating System / Kernel.
@@ -787,22 +1037,22 @@ http://tldp.org/LDP/abs/html/internalvariables.html
This can be used to add conditional support for different Operating
Systems without needing to call `uname`.
```sh
: "$OSTYPE"
```shell
"$OSTYPE"
```
### Get the current working directory.
This is an alternative to the `pwd` built-in.
```sh
: "$PWD"
```shell
"$PWD"
```
### Get the number of seconds the script has been running.
```sh
: "$SECONDS"
```shell
"$SECONDS"
```
## Other
@@ -814,6 +1064,8 @@ in place of the `date` command in a lot of cases.
**NOTE:** Requires `bash` 4+
**Example Function:**
```sh
date() {
# Usage: date "format"
@@ -835,22 +1087,22 @@ date() {
### Bypass shell aliases.
```sh
```shell
# alias
: ls
ls
# command
# shellcheck disable=SC1001
: \ls
\ls
```
### Bypass shell functions.
```sh
```shell
# function
: ls
ls
# command
: command ls
command ls
```

View File

@@ -138,7 +138,7 @@ assert_equals() {
}
main() {
source <(awk '/```sh/{f=1;next}/```/{f=0}f' README.md) 2>/dev/null
source <(awk '/```sh$/{f=1;next}/```/{f=0}f' README.md) 2>/dev/null
head="-> Running tests on the Pure Bash Bible.."
printf '\n%s\n%s\n' "$head" "${head//?/-}"