POSIX catch newline in case statement

I want to catch if a variable is multiline in a case statement in POSIX shell (dash).

I tried this:

case "$q" in
    *$'n'*) echo nl;;
    *) echo NO nl;;

It returns nl in zsh but NO nl in dash.


Asked By: aaa


The dash shell does not have C-strings ($'...'). C-strings is an extension to the POSIX standard. You would have to use a literal newline. This is easier (and looks nicer) if you store the newline in a variable:



for string; do

    case $string in
            printf '"%s" contains newlinen' "$string"
            printf '"%s" does not contain newlinen' "$string"


For each command line argument given to the script, this detects whether it contains a newline or not. The variable used in the case statement ($string) does not need quoting, and the ;; after the last case label is not needed.

Testing (from an interactive zsh shell, which is where the dquote> secondary prompt comes from):

$ dash script.sh "hello world" "hello
dquote> world"
"hello world" does not contain newline
world" contains newline
Answered By: Kusalananda

You can include a literal newline (in quotes) as the pattern, just as you did in assigning to the variable:

case "$q" in
'*) echo nl;;
    *) echo NO nl;;

This makes the formatting ugly (you cannot indent the end quote), but should be fully portable. I tested in bash, zsh, ksh, and dash.

Answered By: Gordon Davisson
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.