How to use mod operator in bash?

BashModuloArithmetic Expressions

Bash Problem Overview


I'm trying a line like this:

for i in {1..600}; do wget http://example.com/search/link $i % 5; done;

What I'm trying to get as output is:

wget http://example.com/search/link0
wget http://example.com/search/link1
wget http://example.com/search/link2
wget http://example.com/search/link3
wget http://example.com/search/link4
wget http://example.com/search/link0

But what I'm actually getting is just:

    wget http://example.com/search/link

Bash Solutions


Solution 1 - Bash

Try the following:

 for i in {1..600}; do echo wget http://example.com/search/link$(($i % 5)); done

The $(( )) syntax does an arithmetic evaluation of the contents.

Solution 2 - Bash

for i in {1..600}
do
    n=$(($i%5))
    wget http://example.com/search/link$n
done

Solution 3 - Bash

You must put your mathematical expressions inside $(( )).

One-liner:

for i in {1..600}; do wget http://example.com/search/link$(($i % 5)); done;

Multiple lines:

for i in {1..600}; do
    wget http://example.com/search/link$(($i % 5))
done

Solution 4 - Bash

This might be off-topic. But for the wget in for loop, you can certainly do

curl -O http://example.com/search/link[1-600]

Solution 5 - Bash

This post is rather old but I thought I would contribute since I stumbled upon it while trying to research the same issue of setting keyboard color through automation.

I created a simple BASH script that I call from my ROOT chrontab every minute to set the keyboard color as the day progresses. You can tweak the color patterns and the modulo to match your needs. This is just a good starting point.

#!/bin/bash
# must run as ROOT to work
# put in your root crontab to change the color at set times

sec=$(date +%s)
min=$(( $sec / 60 ))
col=$(( $min % 7 ))
colors=('0000FF' '00FF00' '00FFFF' 'FF0000' 'FF00FF' 'FFFF00' 'FFFFFF')
colorFile="/sys/class/leds/system76_acpi::kbd_backlight/color"

if [ -f "$colorFile" ]; then
	echo "Set keyboard to color $col ~ ${colors[$col]}"
	echo "${colors[$col]}" > "$colorFile"
fi

Hope you like it.

Solution 6 - Bash

How to use all bash operators, and arithmetic expansion, in bash

Of the 346k visitors to this question thus far, I'd be willing to bet 344.9k of them just want the title of this question answered :

> How to use mod operator in bash?

Even I googled "bash modulus" looking for that answer, and landed here. So, now that I've figured it out, let's just jump straight to it:

How to use the modulus (%) operator in bash

Just do this, for instance:

# 7 mod 4 (answer is 3, but to print the output you must use one of the cmds
# below)
$((7 % 4))

# [PREFERRED: no quotes]
# print the result (double quotes are not required)
echo $((7 % 4))

# print the result (with double quotes if you like)
echo "$((7 % 4))"

Example with variables:

num1="7"
num2="4"

# [PREFERRED: no $ signs nor extraneous quotes] result is 3
echo $((num1 % num2))

# Also ok: with $ signs
echo $(($num1 % $num2))

# Also ok: with $ signs and extra quotes
echo "$(("$num1" % "$num2"))"

Store the result into a variable:

mod=$((num1 % num2))
echo "$mod"  # result is 3

The main links to study for these concepts are these, from the official GNU bash user manual:

  1. Bash Arithmetic Expansion
  2. Bash Shell Arithmetic

More on bash "arithmetic expansion"

I learned the above from @Mark Longair's answer (although it took me some effort to comprehend it all), and that's where I got the link just below. I then did more research.

The $(( )) part is called "Arithmetic Expansion", and is described in the official GNU bash user manual here: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Arithmetic-Expansion.

Basic examples (place echo in front of each one to see the result print to the screen):

# general form
$((mathematical_expression))

# addition
$((7 + 4))  # 11

# subtraction
$((7 - 4))  # 3

# modulus (remainder)
$((7 % 4))  # 3

# logical AND
$((7 && 4))  # 1

# bitwise AND
$((7 & 4))  # 4

# etc.
# See the full operator list below for more

Double quotes around the arithmetic expansion are not needed. From the manual above (emphasis added):

> The expression is treated as if it were within double quotes, but a double quote inside the parentheses is not treated specially. All tokens in the expression undergo parameter and variable expansion, command substitution, and quote removal. The result is treated as the arithmetic expression to be evaluated. Arithmetic expansions may be nested.

For all shell arithmetic operators, see the "Shell Arithmetic" section of the GNU bash manual here: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Arithmetic

You essentially have all of the C language mathematical operators at your disposal. The arithmetic is done "in fixed-width integers with no check for overflow", so if you do echo $((11/10)) or echo $((19/10)) you'll get 1 in both cases since the fractional part is truncated for integers.

From the manual link just above (emphasis added): > Evaluation is done in fixed-width integers with no check for overflow, though division by 0 is trapped and flagged as an error. The operators and their precedence, associativity, and values are the same as in the C language.

Since the arithmetic operators in bash have the same precedence as in C, as it states above, you can also reference the C Operator Precedence from the cppreference community wiki here: https://en.cppreference.com/w/c/language/operator_precedence <-- put that in your toolbag.

Shell Arithmetic: here are all of the supported operators from the GNU Bash manual

They are listed in order of highest to lowest precedence:

> 1. id++ id--
> 1. variable post-increment and post-decrement > 1. ++id --id
> 1. variable pre-increment and pre-decrement > 1. - +
> 1. unary minus and plus > 1. ! ~
> 1. logical and bitwise negation > 1. **
> 1. exponentiation > 1. * / %
> 1. multiplication, division, remainder > 1. + -
> 1. addition, subtraction > 1. << >>
> 1. left and right bitwise shifts > 1. <= >= < >
> 1. comparison > 1. == !=
> 1. equality and inequality > 1. &
> 1. bitwise AND > 1. ^
> 1. bitwise exclusive OR > 1. |
> 1. bitwise OR > 1. &&
> 1. logical AND > 1. ||
> 1. logical OR > 1. expr ? expr : expr
> 1. conditional operator > 1. = *= /= %= += -= <<= >>= &= ^= |=
> 1. assignment > 1. expr1 , expr2
> 1. comma

Using alternate bases in your arithmetic, such as binary (base-2), octal (base-8), and hex (base-16)

To learn about using different bases, such as base-2 (binary), base-8 (octal) or base-16 (hex) with the bash arithmetic operators, read the next couple paragraphs below the "Shell Arithmetic" list above in the manual.

Here are a few quick examples with input numbers which are decimal (base-10), octal (base-8), hex (base-16), and binary (base-2), used in the math:

# hex 0xa (decimal 10) + decimal 5 = decimal 15
echo $((0xa + 5))  # prints `15` (decimal 15)
# OR (same thing)
echo $((16#a + 5))  # prints `15` (decimal 15)

# octal 071 (decimal 57) + hex 0xaa (decimal 170) = decimal 227
echo $((071 + 0xaa))  # prints `227` (decimal 227)
# OR (same thing)
echo $((8#71 + 16#aa))  # prints `227` (decimal 227)

# binary 1011 (decimal 11) + decimal 2 = decimal 13
echo $((2#1011 + 2))  # prints `13` (decimal 13)

# binary 1111 (decimal 15) + binary 11111 (decimal 31) = decimal 46
echo $((2#1111 + 2#11111))  # prints `46` (decimal 46)

To print as hex, use printf "0x%X\n" number:

# prints `0x2E` (hex 2E, or decimal 46)
printf "0x%X\n" $((2#1111 + 2#11111))

To print as binary, use bc (see my answer here):

# prints `0b101110` (decimal 46)
printf "0b%s\n" "$(echo "obase=2; $((2#1111 + 2#11111))" | bc)"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEricView Question on Stackoverflow
Solution 1 - BashMark LongairView Answer on Stackoverflow
Solution 2 - BashChris EberleView Answer on Stackoverflow
Solution 3 - BashHigor E.View Answer on Stackoverflow
Solution 4 - Bashh__View Answer on Stackoverflow
Solution 5 - BashGlenn J. SchworakView Answer on Stackoverflow
Solution 6 - BashGabriel StaplesView Answer on Stackoverflow