String Utilities¶
This section covers string manipulation, formatting, evaluation, and safe quoting/unquoting utilities.
Safe Unquoting with L_unquote¶
L_unquote is a utility for safely unquoting and splitting a string according to shell quoting rules without risk of command execution or shell expansions.
Why not eval or declare?¶
Standard Bash methods for parsing and unquoting strings (such as eval or declare) can be highly dangerous when processing untrusted input. They evaluate and execute arbitrary code embedded in backticks or command substitutions.
For example, using declare:
# This EXECUTEs the command inside $(...)!
declare -a array='($(echo "system compromised" >&2))'
L_unquote parses the string token-by-token in pure Bash. It handles single quotes, double quotes, escape characters, and ANSI-C quoting ($''), without ever evaluating or executing any part of the string.
Basic Usage¶
You can parse a string and store the resulting array in a variable using -v <var_name>.
# Safely split a quoted string into an array
L_unquote -v my_array "ls -l 'somefile; rm -rf ~'"
# View the result
declare -p my_array
# Output: declare -a my_array=([0]="ls" [1]="-l" [2]="somefile; rm -rf ~")
Options¶
-v <var>: Store the parsed tokens into an array variable of that name instead of printing them.-c: Treat#as the start of a comment and ignore the rest of the line.-A: Disable ANSI-C quoting ($'') support.-q: Without-v, instead of printing one word per line, print words quoted withprintf %q.
Safe Quoting Family¶
Quoting strings in Bash is essential to prevent unintended expansion, word splitting, or execution when variables are evaluated. L_lib provides a robust family of quoting functions tailored for different needs and Bash versions.
L_quote¶
L_quote is the primary, portable quoting utility.
- On Bash 4.4+, it utilizes the native and efficient parameter expansion ${*@Q}.
- On older Bash versions, it automatically falls back to L_quote_printf.
L_quote -v quoted "hello 'world' & directory/name"
echo "$quoted"
# Output: 'hello '\''world'\'' & directory/name'
L_quote_printf¶
Uses Bash's builtin printf %q to format multiple arguments as a single string, safely avoiding trailing whitespace issues that occur with simple printf -v var "%q " "$@".
L_quote_printf -v quoted "arg1" "arg2 with spaces"
echo "$quoted"
# Output: arg1 arg2\ with\ spaces
L_quote_setx¶
Leverages Bash's internal set -x (xtrace) formatter to output a string in the exact same style that the shell uses for trace outputs.
L_quote_setx -v quoted "foo'bar" "baz"
Templating & Formatting¶
L_lib provides powerful templating and formatting helpers that resemble higher-level languages.
L_fstring (f-strings)¶
A pure-Bash implementation of Python-style f-strings. It parses named or indexed placeholders (such as {name} or {var[index]}) and formats them using printf under the hood.
name="John"
declare -A age=([John]=42)
# Formats using the age associative array and applies formatting padding (:10s)
L_fstring 'Hello, {name}! You are {age[John]:10s} years old.\n'
# Output: Hello, John! You are 42 years old.
L_percent_format¶
A pure-Bash implementation of Python-style percent formatting (%(key)s).
name="John"
declare -A age=([John]=42)
L_percent_format "Hello, %(name)s! You are %(age[John])10s years old.\n"
# Output: Hello, John! You are 42 years old.
Float Operations in Pure Bash¶
Because standard Bash arithmetic (( ... )) does not support floating-point numbers, scripts usually fall back to calling slow subshells running bc. L_lib offers fast, built-in floating point operations.
L_float_cmp¶
Compares two floating-point numbers using integer alignment and padding without invoking external binaries. This makes it incredibly fast and lightweight.
Supported Operators:¶
- Standard operators:
-lt(or<),-le(or<=),-eq(or==),-ne(or!=),-ge(or>=),-gt(or>). - Spaceship operator (
<=>): Performs a three-way comparison, returning specific exit codes instead of standard true (0) or false (1):- 9: if
$1 < $2 - 10: if
$1 == $2 - 11: if
$1 > $2
- 9: if
# Returns exit code 0 (success) because 123.234 <= 234.345
L_float_cmp 123.234 -le 234.345
echo $? # 0
# Supports more complex comparisons
if L_float_cmp 3.14159 ">=" 3.14; then
echo "Greater or equal!"
fi
# Using the spaceship operator
L_float_cmp 1.1 <=> 1.1
echo $? # 10
L_float¶
A simple wrapper around awk for evaluating floating-point expressions when full arithmetic calculations are required.
Options:¶
-v <var>: Store the output in variable instead of printing it.
# Direct print
L_float "3.14159 * 2.0"
# Output: 6.28318
# Assign to a variable
L_float -v result "3.14159 * 2.0"
echo "$result"
# Output: 6.28318
Fuzzy Searching with L_fuzzy¶
L_fuzzy performs wildcard-based fuzzy matching on a list of candidate strings using an input search query, returning the matched items.
# Search for 'fz' in list of words
L_fuzzy -v results "fz" "fuzzy" "fizzy" "fast" "focus"
declare -p results
# Output: declare -a results=([0]="fuzzy" [1]="fizzy")
API Reference¶
string
¶
Collection of functions to manipulate strings.
L_is_true
¶
Return 0 if the string happend to be something like true.
Return 0 when argument is case-insensitive: - true - 1 - yes - y - t - any number except 0 - the character '+'
Argument:
$1
str
L_is_false
¶
Return 0 if the string happend to be something like false.
Return 0 when argument is case-insensitive: - false - 0 - no - F - n - the character minus '-'
Argument:
$1
str
L_is_true_locale
¶
Return 0 if the string happend to be something like true in locale.
Argument:
$1
str
L_is_false_locale
¶
Return 0 if the string happend to be something like false in locale.
Argument:
$1
str
L_isprint
¶
Return 0 if all characters in string are printable
Argument:
$1
string to check
L_isdigit
¶
Return 0 if all string characters are digits
Argument:
$1
string to check
L_is_valid_variable_name
¶
Return 0 if argument could be a variable name.
This function is used to make sure that eval "$1=" will e correct if L_is_valid_variable_name "$1".
Argument:
$1
string to check
See: L_is_valid_variable_or_array_element
L_is_valid_variable_or_array_element
¶
Return 0 if argument could be a variable name or array element.
Example
L_is_valid_variable_or_array_element aa # true
L_is_valid_variable_or_array_element 'arr[elem]' # true
L_is_valid_variable_or_array_element 'arr[elem' # false
Argument:
$1
string to check
L_is_valid_function_name
¶
Is the string a valid Bash opinionated function name?
Almost anything is valid Bash function name.
Argument:
$1
string to check
See:
L_is_integer
¶
Return 0 if the string characters is an integer
Argument:
$1
string to check
L_is_float
¶
Return 0 if the string characters is a float
Argument:
$1
string to check
$L_NL
¶
newline
$L_TAB
¶
tab
$L_SOH
¶
Start of heading
$L_STX
¶
Start of text
$L_EOT
¶
End of Text
$L_EOF
¶
End of transmission
$L_ENQ
¶
Enquiry
$L_ACK
¶
Acknowledge
$L_BEL
¶
Bell
$L_BS
¶
Backspace
$L_HT
¶
Horizontal Tab
$L_LF
¶
Line Feed
$L_VT
¶
Vertical Tab
$L_FF
¶
Form Feed
$L_CR
¶
Carriage Return
$L_SO
¶
Shift Out
$L_SI
¶
Shift In
$L_DLE
¶
Data Link Escape
$L_DC1
¶
Device Control 1
$L_DC2
¶
Device Control 2
$L_DC3
¶
Device Control 3
$L_DC4
¶
Device Control 4
$L_NAK
¶
Negative Acknowledge
$L_SYN
¶
Synchronous Idle
$L_ETB
¶
End of Transmission Block
$L_CAN
¶
Cancel
$L_EM
¶
End of Medium
$L_SUB
¶
Substitute
$L_ESC
¶
Escape
$L_FS
¶
File Separator
$L_GS
¶
Group Separator
$L_RS
¶
Record Separator
$L_US
¶
Unit Separator
$L_DEL
¶
Delete
$L_LBRACE
¶
Left brace character
$L_RBRACE
¶
Right brace character
$L_UUID
¶
Looks random.
See: L_uuid4
$L_ALLCHARS
¶
255 bytes with all possible 255 values
$L_ASCII_LOWERCASE
¶
All lowercase characters a-z
$L_ASCII_UPPERCASE
¶
All uppercase characters A-Z
$L_GPL_LICENSE_NOTICE_3_OR_LATER
¶
The GPL3 or later License notice.
See: https://www.gnu.org/licenses/gpl-howto.en.html#license-notices
$L_FREE_SOFTWARE_NOTICE
¶
notice that the software is a free software.
L_quote_setx
¶
Output a string with the same quotating style as does bash in set -x
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$@
arguments to quote
L_quote_setx_vL_RET
¶
L_quote_printf
¶
Output a string with the same quotating style as does bash with printf
For single argument, just use printf -v var "%q" "$var".
Use this for more arguments, like printf -v var "%q " "$@" results in a trailing space.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$@
arguments to quote
L_quote_printf_vL_RET
¶
L_quote_bin_printf
¶
Output a string with the same quotating style as does /bin/printf
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$@
arguments to quote
L_quote_bin_printf_vL_RET
¶
L_quote
¶
Quotes a string for bash to be able to re-read it.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$@
arguments to quote
L_quote_vL_RET
¶
L_strhash
¶
Convert a string to a number.
Option:
-v <var>
Store the output in variable instead of printing it.
L_strhash_vL_RET
¶
L_strhash_bash
¶
Convert a string to a number in pure bash.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
string
L_strhash_bash_vL_RET
¶
L_strstr
¶
Check if string contains substring.
Arguments:
-
$1string -
$2substring
L_strupper
¶
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
String to operate on.
L_strlower
¶
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
String to operate on.
L_capitalize
¶
Capitalize first character of a string.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
String to operate on
L_uncapitalize
¶
Lowercase first character of a string.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
String to operate on
L_strip
¶
Remove characters from IFS from begining and end of string
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1String to operate on. -
[$2]Optional glob to strip, default is [:space:]
L_strip_vL_RET
¶
Shellcheck disable= SC2295
L_lstrip
¶
Remove characters from IFS from begining of string
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1String to operate on. -
[$2]Optional glob to strip, default is [:space:]
L_lstrip_vL_RET
¶
Shellcheck disable= SC2295
L_rstrip
¶
Remove characters from IFS from begining of string
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1String to operate on. -
[$2]Optional glob to strip, default is [:space:]
L_rstrip_vL_RET
¶
Shellcheck disable= SC2295
L_list_functions_with_prefix
¶
list functions with prefix
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
prefix
L_list_functions_with_prefix_vL_RET
¶
L_list_functions_with_prefix_removed
¶
list functions with prefix and remove the prefix
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
prefix
See: L_list_functions_with_prefix
L_list_functions_with_prefix_removed_vL_RET
¶
L_abbreviation
¶
Choose elements matching prefix.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1prefix -
$@elements
L_abbreviation_vL_RET
¶
L_float_cmp
¶
compare two float numbers
The '<=>' operator returns 9 when $1 < $2, 10 when $1 == $2 and 11 when $1 > $2.
Example
L_float_cmp 123.234 -le 234.345
echo $? # outputs 0
L_exit_into ret L_float_cmp 123.234 -le 234.345
echo "$ret" # outputs 0
Arguments:
-
$1one number -
$2operator, one of -lt -le -eq -ne -gt -ge > >= == != <= < <=> -
$3second number
L_float
¶
A simple wrapper script around awk to evaluate float expressions.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
Expression to evaluate.
L_float_vL_RET
¶
L_percent_format
¶
Print a string with percent format.
Simple implementation of percent formatting in bash using regex and printf.
Example
name=John
declare -A age=([John]=42)
L_percent_format "Hello, %(name)s! You are %(age[John])10s years old.\n"
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1format string -
$@arguments
L_percent_format_vL_RET
¶
Shellcheck disable= SC2059
L_fstring
¶
print a string with f-string format
A simple implementation of f-strings in bash using regex and printf.
Example
name=John
declare -A age=([John]=42)
L_fstring 'Hello, {name}! You are {age[John]:10s} years old.\n'
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1Format string -
$@Arguments {$1} {$2} etc.
L_fstring_vL_RET
¶
Shellcheck disable= SC2059
L_hexdump
¶
Convert a string to hex dump.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
L_hexdump_vL_RET
¶
L_urlencode
¶
Encode a string in percent encoding.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
L_urlencode_vL_RET
¶
L_urldecode
¶
Decode percent encoding.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
L_urldecode_vL_RET
¶
L_html_escape
¶
Escape characters for html.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
L_html_escape_vL_RET
¶
L_string_replace
¶
Replace multiple characters in a string in order.
Note
I think this should be removed.
Example
L_string_replace -v string "$string" "&" "&" "<" "<"
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1String to operate on. -
$2String to replace. -
$3Replacement. -
$@String to replace and replacement can be repeated multiple times.
See: L_html_escape
L_string_replace_vL_RET
¶
L_string_count
¶
Count the character in string.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1String. -
$2Character to count in string.
L_string_count_vL_RET
¶
L_string_count_lines
¶
Count lines in a string.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1String. -
[$2]Line characters. Default: newline.
L_string_count_lines_vL_RET
¶
L_unquote
¶
Split a string with quotes without the risk of execution anything.
Rules: - https://www.gnu.org/software/bash/manual/html_node/Escape-Character.html - https://www.gnu.org/software/bash/manual/html_node/Single-Quotes.html - https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html - https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html
Why not xargs? To support ANSI-C quoting style $'' and support newlines in quotes.
Why not declare? Declare allows execution, declare -a array='($(echo something >&2))'executes echo.
Example
$ L_unquote -v cmd "ls -l 'somefile; rm -rf ~'"
$ declare -p cmd
declare -a cmd=([0]="ls" [1]="-l" [2]="somefile; rm -rf ~")
Options:
-
-v <var>Store the output in variable instead of printing it. -
-cEnable ignoring comments. -
-ADisable ANSI-C quoting. -
-hPrint this help and return 0. -
-qWithout -v, instead of printing one word per line, output words quoted withprintf %q.
Shellcheck disable= SC1003
L_fuzzy
¶
Fuzzy search a key in a list of strings, returning matches in L_RET.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1Key to search for -
$@Candidate strings