Search code examples
bashshellprintfdouble-quotes

How the shell constructs a string by looping


I need to construct redis dummy data, and when constructing redis hash data, I want to construct hash data for a large number of fields through a for loop.

I call the printf construct directly to achieve the desired result, but when stored in a variable, the result is not as expected, the sample code is as follows

#!/bin/bash
for no in $(seq 5); do
    printf "%s%s %s " "$data" "filed$no" "val$no"
done
# stdout: 
# bash test.sh
filed1 val1 filed2 val2 filed3 val3 filed4 val4 filed5 val5

save to variable

#!/bin/bash
data=""
for no in $(seq 5); do
    data="$(printf "%s%s %s " "$data" "filed$no" "val$no")"
done
printf "%s\n" $data

# stdout
# bash test.sh 
filed1
val1
filed2
val2
filed3
val3
filed4
val4
filed5
val5

This seems to be escaping spaces into line breaks, how can I solve it? I really appreciate any help with this.


Solution

  • Quote the variable:

    printf "%s\n" "$data"
    

    When not quoted, $data is expanded into several arguments. printf reuses the format specifier repeatedly for all of its arguments.

    See printf:

    The format is reused as necessary to consume all of the arguments. If the format requires more arguments than are supplied, the extra format specifications behave as if a zero value or null string, as appropriate, had been supplied. The return value is zero on success, non-zero on failure.

    A simple demonstration:

    $ printf "hello %s\n" a b c
    hello a
    hello b
    hello c
    $ printf "hello %s\n" "a b c"
    hello a b c
    $