In a regex, "either the letter p, u, or z" is [puz]
, a number is [0-9]
, and a sequence of numbers is usually either [0-9]+
(one-or-more) if you're using a regex syntax that supports it or [0-9][0-9]*
(zero-or-more) if you're forced to use POSIX Basix Regex which doesn't. Finally add ^...$
to require a full match (anchor the match to start & end of the string, instead of just anywhere within).
As you tagged the question with bash, assuming it's a #!/usr/bin/env bash
script, you can use Bash's [[
with its regex match operator =~
(which uses POSIX Extended regex syntax):
if [[ $user == nobody || $user =~ ^[puz][0-9]+$ ]]; then
if [[ $user =~ ^(nobody|[puz][0-9]+)$ ]]; then
If it weren't Bash but a #!/bin/sh
"POSIX shell" script, you could use expr
for the same task (which is limited to the POSIX Basic dialect of regex and doesn't have +
):
if [ "$user" = nobody ] || expr "$user" : "^[puz][0-9][0-9]*$" > /dev/null; then
or, even, grep (or one of the 20+ other regex-capable tools if performance is not a big concern):
if [ "$user" = nobody ] || (echo "$user" | grep -qs "^[puz][0-9][0-9]*$"); then
if echo "$user" | grep -Eqs "^(nobody|[puz][0-9][0-9]*)$"
Note that [
should use a single =
, even though shells often accept ==
.