How to Extract Numbers from String
• 2 min read
bash regex extraction numbers pattern matching grep sed
Quick Answer: Extract Numbers from String in Bash
To extract numbers from a string, use grep -oE '[0-9]+' for integers or grep -oE '[0-9]+\.[0-9]+' for decimals. For a single variable without pipes, use regex: [[ "$text" =~ ([0-9]+) ]] then access ${BASH_REMATCH[1]}.
Quick Comparison: Number Extraction Methods
| Method | Syntax | Best For | Speed |
|---|---|---|---|
| grep -oE | grep -oE '[0-9]+' | Pipes/files | Fast |
| Regex match | [[ =~ ([0-9]+) ]] | Variables | Fastest |
| sed -n s | sed -n 's/.*\([0-9]*\).*/\1/p' | Piped data | Medium |
| awk match | awk '{match($0, /[0-9]+/); print substr($0, RSTART, RLENGTH)}' | Fields | Medium |
Bottom line: Use grep -oE for pipes; use regex capture for variables.
Extract numeric values from text strings using grep, sed, awk, and regex patterns.
Method 1: Using grep -o (Simplest)
# Extract all numbers
echo "Price: $19.99" | grep -o "[0-9]*"
# Extract floating point
echo "Price: $19.99" | grep -o "[0-9.]*"
# Extract with leading zeros
echo "ID: 00123" | grep -o "[0-9]*"
Using sed
# Remove non-digits
echo "abc123def456" | sed 's/[^0-9]//g'
# Output: 123456
# Extract first number
echo "Price: $19.99" | sed 's/[^0-9.]*//g'
Using awk
# Extract fields with numbers
echo "Item: 5 Price: 19.99" | awk '{print $2, $4}'
# Extract only numeric fields
echo "abc 123 def 456" | awk '{for(i=1;i<=NF;i++) if($i~/^[0-9]+$/) print $i}'
Practical Example: Extract All Numbers
#!/bin/bash
text="$1"
# Extract all integers
numbers=$(echo "$text" | grep -oE '[0-9]+')
echo "Found numbers:"
echo "$numbers"
Usage:
$ ./extract_numbers.sh "The prices are 10, 20, 30 dollars"
Found numbers:
10
20
30
Extract Numbers from Variables
#!/bin/bash
string="Order #12345 total: $99.99"
# Remove non-digits
order=$(echo "$string" | sed 's/[^0-9]//g')
echo "All digits: $order"
# Extract first number only
first=$(echo "$string" | grep -oE '[0-9]+' | head -1)
echo "First number: $first"
# Extract decimal
price=$(echo "$string" | grep -oE '[0-9]+\.[0-9]+')
echo "Price: $price"
Output:
All digits: 12345999.99
First number: 12345
Price: 99.99
Using Bash Parameter Expansion
#!/bin/bash
string="The answer is 42!"
# Remove leading non-digits
result="${string##*([^0-9])}"
result="${result%%[^0-9]*}"
echo "$result" # Output: 42
Extract with Regex Capture
#!/bin/bash
text="Invoice #INV-2026-001 for $500.00"
# Extract invoice number using regex
if [[ $text =~ INV-([0-9]+)-([0-9]+) ]]; then
year="${BASH_REMATCH[1]}"
num="${BASH_REMATCH[2]}"
echo "Invoice: $year-$num"
fi
# Extract price
if [[ $text =~ \$([0-9]+\.[0-9]+) ]]; then
price="${BASH_REMATCH[1]}"
echo "Amount: $price"
fi
Output:
Invoice: 2026-001
Amount: 500.00
Extract and Sum
#!/bin/bash
# Extract all numbers and sum them
text="Scores: 95, 87, 92, 88"
sum=$(echo "$text" | grep -oE '[0-9]+' | awk '{sum+=$1} END {print sum}')
echo "Total: $sum"
Output:
Total: 362
Multiple Patterns
#!/bin/bash
# Extract multiple types of numbers
text="Phone: 555-123-4567 Date: 2026-02-21 Price: $99.99"
# Phone
phone=$(echo "$text" | grep -oE '[0-9]{3}-[0-9]{3}-[0-9]{4}')
# Date
date=$(echo "$text" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}')
# Price
price=$(echo "$text" | grep -oE '\$[0-9]+\.[0-9]{2}')
echo "Phone: $phone"
echo "Date: $date"
echo "Price: $price"
From File Lines
#!/bin/bash
# Extract numbers from each line
file="data.txt"
while IFS= read -r line; do
# Get first number from line
num=$(echo "$line" | grep -oE '[0-9]+' | head -1)
echo "Line: $line → Number: $num"
done < "$file"
Common Mistakes
- Using wrong regex -
[0-9]*matches zero digits - Not escaping dots - use
\.for literal dot - Not quoting strings - failures with spaces
- Wrong grep flags - use
-oto get match only
Key Points
- Use
[0-9]+for one or more digits - Use
[0-9.]+for decimals - Use
-oflag with grep - Quote variables properly
- Test patterns with sample data
Summary
Extracting numbers from strings is common in shell scripts. Use grep -o for simple cases, awk for field-based extraction, and regex with capture groups for complex patterns.