Author’s Note:
I’m learning as I write this series, just like many of you! If you spot mistakes or have ideas to improve the explanations or code, please share your thoughts in the comments. I’m open to feedback and eager to grow alongside this community.
Introduction
If you’re new to Linux programming, you’ll quickly realize that strings and numbers are at the heart of writing effective scripts and tools. From automating system tasks to processing files, knowing how to manipulate data at this level is crucial.
In this article, you’ll learn the essentials of working with Linux strings and numbers in Bash, covering variable expansion, string manipulation, arithmetic, and practical scripting tips.
Understanding Data in Linux
Linux treats most data as either files, strings, or numbers. While files are often the focus, many problems require working with smaller fragments—like the contents of a variable or a line in a file. Mastering string and number operations unlocks powerful scripting abilities.
What is a String in Linux?
A string is simply a sequence of characters—letters, numbers, spaces, or symbols. In Bash, strings are stored in variables and manipulated using built-in shell features.
Example:
greeting="Hello, Linux!"
echo $greeting
What is a Number in Linux?
A number in Linux scripting usually means an integer or floating-point value stored in a variable. Numbers are used for calculations, loop counters, or as input/output in scripts.
Example:
count=42
echo $count
Variables and Parameter Expansion
Parameter expansion allows you to access and manipulate variable values. The simplest forms are $variable
or ${variable}
.
Key points: - Use braces (${a}
) when appending text:
bash a="foo" echo "${a}_file" # Outputs: foo_file
- For positional parameters above 9, use braces:
${11}
Managing Empty and Unset Variables
Bash provides special expansions to handle variables that might be empty or unset:
Expansion | Purpose | Example |
---|---|---|
${parameter:-word} |
Use word if parameter is unset or empty |
echo ${foo:-"default"} |
${parameter:=word} |
Assign word if parameter is unset or empty, then use it |
echo ${foo:="default"} |
${parameter:?word} |
Print word as error and exit if parameter is unset or empty |
echo ${foo:?"Error: foo is empty"} |
${parameter:+word} |
Use word only if parameter is set and non-empty |
echo ${foo:+"foo is set"} |
String Length and Substrings
Get string length:
foo="This string is long." echo ${#foo} # Outputs: 20
Extract substring:
echo ${foo:5} # Outputs: string is long. echo ${foo:5:6} # Outputs: string echo ${foo: -5} # Outputs: long. echo ${foo: -5:2} # Outputs: lo
Pattern Matching and String Manipulation
Remove prefix:
file="file.txt.zip" echo ${file#*.} # txt.zip echo ${file##*.} # zip
Remove suffix:
echo ${file%.*} # file.txt echo ${file%%.*} # file
Search and replace:
foo="JPG.JPG" echo ${foo/JPG/jpg} # jpg.JPG (first match) echo ${foo//JPG/jpg} # jpg.jpg (all matches) echo ${foo/#JPG/jpg} # jpg.JPG (must be at start) echo ${foo/%JPG/jpg} # JPG.jpg (must be at end)
Case Conversion in Bash
Modern Bash versions let you convert case easily:
Expansion | Result | Example |
---|---|---|
${var,,} |
All lowercase | ${foo,,} |
${var,} |
First character to lowercase | ${foo,} |
${var^^} |
All uppercase | ${foo^^} |
${var^} |
First character to uppercase | ${foo^} |
Script Example:
input="aBc"
echo ${input,,} # abc
echo ${input^^} # ABC
Arithmetic Expansion and Evaluation
Bash supports arithmetic directly:
Arithmetic expansion:
echo $(( 5 + 3 )) # 8
Compound command for tests:
if (( count > 10 )); then echo "Greater than 10" fi
Working with Number Bases
You can use different bases (decimal, octal, hexadecimal, binary) in Bash arithmetic:
Notation | Meaning | Example |
---|---|---|
255 |
Decimal (default) | echo $((255)) |
0377 |
Octal (leading zero) | echo $((0377)) |
0xff |
Hexadecimal (0x prefix) | echo $((0xff)) |
2#11111111 |
Binary (base#number) | echo $((2#11111111)) |
Arithmetic Operators in Bash
Operator | Description | Example |
---|---|---|
+ |
Addition | $((5 + 2)) |
- |
Subtraction | $((5 - 2)) |
* |
Multiplication | $((5 * 2)) |
/ |
Integer Division | $((5 / 2)) # 2 |
** |
Exponentiation | $((2 ** 3)) # 8 |
% |
Modulo (remainder) | $((5 % 2)) # 1 |
Modulo Example:
for ((i = 0; i <= 20; ++i)); do
if ((i % 5 == 0)); then
printf "<%d> " $i
else
printf "%d " $i
fi
done
printf "\n"
# Output: <0> 1 2 3 4 <5> 6 7 8 9 <10> 11 12 13 14 <15> 16 17 18 19 <20>
Assignment and Increment/Decrement Operators
- Assignment:
foo=5
- Add:
((foo += 2))
- Subtract:
((foo -= 2))
- Multiply:
((foo *= 2))
- Divide:
((foo /= 2))
- Modulo:
((foo %= 2))
- Increment/Decrement:
((foo++))
,((--foo))
Prefix vs Postfix:
foo=1
echo $((foo++)) # 1 (value before increment)
echo $foo # 2
foo=1
echo $((++foo)) # 2 (value after increment)
Bitwise Operations
Operator | Description | Example |
---|---|---|
~ |
Bitwise NOT | $((~5)) |
<< |
Left shift | $((1 << 3)) # 8 |
>> |
Right shift | $((8 >> 3)) # 1 |
& |
Bitwise AND | $((5 & 3)) # 1 |
| |
Bitwise OR | $((5 | 3)) # 7 |
^ |
Bitwise XOR | $((5 ^ 3)) # 6 |
Example:
for ((i=0;i<8;++i)); do echo $((1<<i)); done
# Outputs: 1 2 4 8 16 32 64 128
Thank you for the full text! I’ll continue the article from where we left off, ensuring the next sections are clear, practical, and beginner-friendly. References and example scripts will be included as shown in your file.
Logical and Comparison Operators
In Bash arithmetic, you can use a variety of comparison and logical operators within the (( ))
compound command:
Operator | Description | Example |
---|---|---|
< |
Less than | ((a < b)) |
<= |
Less than or equal to | ((a <= b)) |
> |
Greater than | ((a > b)) |
>= |
Greater than or equal to | ((a >= b)) |
== |
Equal to | ((a == b)) |
!= |
Not equal to | ((a != b)) |
&& |
Logical AND | ((a > 0 && b < 5)) |
\|\| |
Logical OR | ((a == 0 || b == 0)) |
expr1?expr2:expr3 |
Ternary operator | ((a < 1 ? ++a : --a)) |
Zero evaluates to false, non-zero to true.
if ((num > 10)); then
echo "Number is greater than 10"
fi
Ternary Operator Example:
a=0
((a<1?++a:--a))
echo $a # Output: 1
((a<1?++a:--a))
echo $a # Output: 0
Parentheses are sometimes needed for assignments: ((a<1?(a+=1):(a-=1)))
Using bc
for Advanced Math
Bash can only handle integer arithmetic. For floating-point calculations or more advanced math, use the bc
command.
Basic Usage
Interactive:
$ bc -q 5.7 * 3.2 18.24 quit
Scripted:
result=$(bc <<< "scale=4; 10/3") echo $result # Outputs: 3.3333
Practical Script Example: Monthly Loan Payment Calculator
#!/bin/bash
# loan-calc : script to calculate monthly loan payments
if (($# != 3)); then
echo "Usage: $0 PRINCIPAL INTEREST MONTHS"
exit 1
fi
principal=$1
interest=$2
months=$3
bc <<- EOF
scale = 10
i = $interest / 12
p = $principal
n = $months
a = p * ((i * ((1 + i) ^ n)) / (((1 + i) ^ n) - 1))
print a, "\n"
EOF
Run example:
$ ./loan-calc 135000 0.0775 180
1270.7222490000
Practical Script Example: Find Longest Word in a File
Here’s a script using string length expansion and the strings
command to find the longest word in a file:
#!/bin/bash
# longest-word : find longest string in a file
for i; do
if [[ -r $i ]]; then
max_word=
max_len=0
for j in $(strings "$i"); do
len=${#j}
if (( len > max_len )); then
max_len=$len
max_word=$j
fi
done
echo "$i: '$max_word' ($max_len characters)"
fi
shift
done
Performance Tip:
Using parameter expansion for string length is much faster than spawning a subshell with wc -c
.
Common Pitfalls and Best Practices
- Quoting variables: Always quote variables unless you want word splitting.
- Integer math only in Bash: Use
bc
for decimals. - Uninitialized variables: Use
${parameter:-default}
to avoid errors. - External commands vs. expansions: Prefer shell parameter expansions over calling
sed
,cut
, orwc
for simple string manipulations—they’re faster! - Case normalization: Convert user input to a consistent case for comparisons.
Your Turn!
Challenge:
Write a Bash script that accepts a string as input and outputs the string reversed (e.g., “hello” → “olleh”) using only parameter expansion.
See Solution
#!/bin/bash
# reverse-string.sh
input="$1"
reversed=""
for ((i=${#input}-1; i>=0; i--)); do
reversed="$reversed${input:i:1}"
done
echo "$reversed"
Usage:
$ ./reverse-string.sh hello
olleh
Key Takeaways
- Parameter expansion is powerful for string and number manipulation in Bash.
- Use
${parameter:-word}
and friends to handle unset or empty variables robustly. - String length and substring extraction are easy with
${#var}
and${var:start:length}
. - Case conversion, pattern matching, and replacement can all be done natively in Bash.
- Bash arithmetic operates only on integers; use
bc
for floating-point math. - Prefer parameter expansion over external commands for performance.
Conclusion
Mastering strings and numbers is essential for effective Linux scripting. With the tools you’ve learned—parameter expansion, arithmetic, pattern matching, and bc
—you can write more powerful and efficient scripts.
Experiment, practice, and don’t hesitate to improve on these examples. The more you play, the better you’ll get!
FAQs
Q1: How do I check if a variable is empty in Bash?
A: Use [ -z "$var" ]
or parameter expansion like ${var:-default}
to detect or fill empty values.
Q2: Can Bash do floating-point math?
A: Not natively. Use the bc
command for decimal calculations.
Q3: What’s the difference between ${var}
and $var
?
A: Braces are needed when appending text, using complex expansions, or referencing positional parameters above 9.
Q4: How do I convert a string to uppercase in Bash?
A: Use ${var^^}
for all uppercase or ${var^}
for just the first character.
Q5: How do I avoid errors with unset variables?
A: Use ${var:-default}
to supply a fallback value if the variable is unset or empty.
Engage!
Did you find this guide helpful?
Please share your feedback, ask questions, or add your own tips in the comments below! If you know someone learning Bash, share this post to help them too.
References
- GNU Bash Reference Manual: Shell Parameter Expansion
- Wikipedia: Bit operation
- Wikipedia: Ternary operation
- Wikipedia: Amortization calculator
Happy Coding! 🚀
You can connect with me at any one of the below:
Telegram Channel here: https://t.me/steveondata
LinkedIn Network here: https://www.linkedin.com/in/spsanderson/
Mastadon Social here: https://mstdn.social/@stevensanderson
RStats Network here: https://rstats.me/@spsanderson
GitHub Network here: https://github.com/spsanderson
Bluesky Network here: https://bsky.app/profile/spsanderson.com
My Book: Extending Excel with Python and R here: https://packt.link/oTyZJ
You.com Referral Link: https://you.com/join/EHSLDTL6