Say a string might be like "a b '' c '' d"
. How can I check that there is single/double quote and space contained in the string?

- 39,467
- 16
- 112
- 140

- 12,661
- 21
- 68
- 78
-
Why do you want to do this? If you're trying to, say, check for an "invalid" file name, you could instead fix the script to support file names with spaces or quotes. For example. – John Kugelman Sep 24 '09 at 20:56
-
Are you saying that you want to know that: a) there is a single/double quote around a space b) a single/double quote along with a space c) something altogether different from that? – ezpz Sep 24 '09 at 21:10
-
Just to check if a string has any single quote and if it has any space – derrdji Sep 28 '09 at 18:44
-
To check if string has ONLY spaces, tabs, or new lines, try: `[[ $string = *[$" \t\n"]* ]]` – Noam Manos May 11 '20 at 15:52
10 Answers
You can use regular expressions in bash:
string="a b '' c '' d"
if [[ "$string" =~ \ |\' ]] # slightly more readable: if [[ "$string" =~ ( |\') ]]
then
echo "Matches"
else
echo "No matches"
fi
Edit:
For reasons obvious above, it's better to put the regex in a variable:
pattern=" |'"
if [[ $string =~ $pattern ]]
And quotes aren't necessary inside double square brackets. They can't be used on the right or the regex is changed to a literal string.

- 346,391
- 90
- 374
- 439
-
cleanest one IMO, for me I also added tab but looks a little funky as I had to throw the dollar-quote in there `pattern=" |'"$'|\t'` - is there a cleaner way? – nhed May 24 '16 at 14:27
-
1@nhed: In the case of single characters, you can use a character pattern instead of the pipe character alternation. This might be slightly less ugly: `pattern=$'[ \'\t]'`. You could also use a variable: `tab=$'\t'; pattern=" |'|$tab"` or a literal tab (which isn't good for readability) by typing it in using Ctrl-V-Tab. – Dennis Williamson May 24 '16 at 14:42
case "$var" in
*\ * )
echo "match"
;;
*)
echo "no match"
;;
esac

- 55,454
- 12
- 93
- 132
-
3
-
-
-
2Thanks for quoting it and setting a good example for scripts in general, even though it's not strictly necessary in this particular instance. – that other guy Aug 03 '18 at 18:40
-
-
-
@Juergen: yeah I was I was looking for a snippet that would do that and I thought the bizarre whitespacing in this one might somehow be doing that, and was just disappointed to see otherwise. :/ – user541686 Jun 05 '19 at 21:06
-
@Mehrdad: lets just be lazy and convert whitespace-characters to spaces: https://superuser.com/a/112837/722736 – Juergen Jun 06 '19 at 22:17
-
@Juergen: It's easy with an external program... I was trying to do it in just Bash (ideally in a POSIX-compliant way) since calling external processes can be pretty slow in comparison. – user541686 Jun 06 '19 at 22:18
You could do this, without the need for any backslashes or external commands:
# string matching
if [[ $string = *" "* ]]; then
echo "string contains one or more spaces"
else
echo "string doesn't contain spaces"
fi
# regex matching
re="[[:space:]]+"
if [[ $string =~ $re ]]; then
echo "string contains one or more spaces"
else
echo "string doesn't contain spaces"
fi
Based on this benchmark, the string match is much faster than the regex one.
Related:

- 39,467
- 16
- 112
- 140
-
3Best most current answer because it specifically answers the question - a space in a string - by providing two options that are portable and very easy to understand during a code review. Please people, like @codeforester, keep it simple; the best software always is. – akahunahi Oct 10 '18 at 04:41
-
2The regex version is more general, since it also finds \t and \n and \r. [:space:] "Whitespace characters such as space, form-feed, newline,carriage return, horizontal tab, and vertical tab" https://www.oreilly.com/library/view/oracle-regular-expressions/0596006012/re08.html – masterxilo Nov 20 '18 at 20:13
[[ "$str" = "${str%[[:space:]]*}" ]] && echo "no spaces" || echo "has spaces"

- 27,102
- 4
- 75
- 71

- 238,783
- 38
- 220
- 352
-
3note that this doesn't detect tabs or newlines, for those who are curious – Dieter_be Apr 14 '13 at 14:09
string="a b '' c '' d"
if [ "$string" == "${string//[\' ]/}" ]
then
echo did not contain space or single quote
else
echo did contain space or single quote
fi

- 376
- 1
- 3
The portable way to do this is with grep
:
S="a b '' c '' d"
if echo $S | grep -E '[ "]' >/dev/null
then
echo "It's a match"
fi
...a bit ugly, but guaranteed to work everywhere.

- 6,920
- 3
- 25
- 29
-
2With `-q` option in grep, the `>/dev/null` not needed anymore. A bit nicer. – Ray Dec 07 '17 at 17:50
How about an approach similar to:
$ A="some string"; echo $A | grep \ | wc -l
1
$ A="somestring"; echo $A | grep \ | wc -l
0
?

- 23,614
- 16
- 68
- 106
function foo() {
echo "String: $*"
SPACES=$(($#-1))
echo "Spaces: $SPACES"
QUOTES=0
for i in $*; do
if [ "$i" == "'" ]; then
QUOTES=$((QUOTES+1))
fi
done
echo "Quotes: $QUOTES"
echo
}
S="string with spaces"
foo $S
S="single' 'quotes"
foo $S
S="single '' quotes"
foo $S
S="single ' ' quotes"
foo $S
yields:
String: string with spaces
Spaces: 2
Quotes: 0
String: single' 'quotes
Spaces: 1
Quotes: 0
String: single '' quotes
Spaces: 2
Quotes: 0
String: single ' ' quotes
Spaces: 3
Quotes: 2

- 11,767
- 6
- 38
- 39
What about this:
[[ $var == ${var//[ \"]/_} ]] && echo "quotes or spaces not found"
or if you like this:
if [[ $var == ${var//[ \"]/_} ]] ; then
echo "quotes or spaces not found"
else
echo "found quotes or spaces"
fi
Explanation: I'm evaluating a comparison between the variable ${var} and the variable ${var} itself after a on-the-fly non-destructive string substitution of all the quotes and spaces with an underscore.
Examples:
${var// /_} # Substitute all spaces with underscores
The following code substitute all characters between the squared brackets (space and quotes) with an underscore. Note that quotes has to be protected with backslash:
${var//[ \"]/_}

- 33
- 6
-
I like the use of this syntax, but you've flipped the search and are seeking the opposite of what OP asked for. Should mention `!=` – Xaekai Apr 15 '20 at 20:45
I do wonder why nobody mentioned the [:space:] set. Usually your not only interested in detecting the space character. I often need to detect any white space, e.g. TAB. The "grep" example would look like this:
$ echo " " | egrep -q "[:space:]" && echo "Has no Whitespace" || echo "Has Whitespace"
Has Whitespace
$ echo "a" | egrep -q "[:space:]" && echo "Has no Whitespace" || echo "Has Whitespace"
Has no Whitespace

- 1,286
- 12
- 12
-
For those interested in this solution, my `grep` informs me that `character class syntax is [[:space:]], not [:space:]`. Otherwise, excellent solution! – jdferreira Mar 21 '13 at 16:55
-
Since question is tagged "bash", no need to start up another process just to test a string: `case "$String" in *[[:space:]]*) echo "match" ;; esac` – Ron Burk May 23 '17 at 19:43