3

I need to do IFS=",";echo {1..5} so that it can output 1,2,3,4,5 instead of 1 2 3 4 5. How do I make bash echo {1..5} and output the values with a comma?

5 Answers 5

7

With Bash's builtins:

This is a bit ugly since we need to separate the 5 to avoid a trailing comma:

$ printf '%s,' {1..4}; echo 5
1,2,3,4,5

Though since printf can output directly to a variable, that can be worked around and the final comma removed with a parameter expansion:

$ printf -v tmpvar "%s," {1..5}; echo "${tmpvar%,}"
1,2,3,4,5

Or with "$*", which joins using the first character of IFS. This trashes global state, but you could rather easily avoid that by running it in a subshell or in a function with local IFS:

$ IFS=,; set -- {1..5}; echo "$*";
1,2,3,4,5

If the limits are in variables, it's probably easiest to just do it manually with a loop since you can't use variables as endpoints in a brace expansion range. Again, the upper limit is in a special case:

a=1; b=5
for (( i=a ; i<b ; i++ )); do
    printf "$i,";
done;
printf "$b\n" 
1
  • In case of variables I think a good way shall be: a=1;b=5; seq --separator="," $a $b Commented Dec 14, 2018 at 14:36
6

Try to use:

seq --separator="," 1 5
4

Since you're using numerical brace expansion, the only spaces that will ever appear are the ones between numbers, so you could post-process the result:

output=$(echo {1..5} | tr ' ' ',')

or

output=$(echo {1..5} | sed 's/ /,/g')
4

This is more to further expand on expansion than to provide a practical solution: what follows is less concise and efficient than the alternatives proposed in other answers.

In Bash, the Internal Field Separator (IFS) is not used for brace expansion—hence, IFS=","; echo {1..5} won't work as you would like. It is used, however, when expanding a few other things, including:

Positional parameters

About the expansion of the special parameter *, quoting man bash:

When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable.

We can use a function to exemplify:

$ function fnc () {
>   IFS=','
>   printf '%s\n' "$*"
> }
$ fnc {1..5}
1,2,3,4,5

Note that this function also sets the value of IFS for the calling environment. This can be avoided in a portable way by enclosing the function body in parentheses (i.e. fnc () ( IFS=... )), with the side effect of having it executed in a subshell, or using local IFS=, to declare a variable which is local to the function (the local builtin is not specified in POSIX, but is available in several shells), or setting IFS back to its original value before the end of the function.

Arrays

When accessing the items of an array using the * subscript, again, quoting man bash:

If the word is double-quoted, ${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS special variable, ...

Example (again, don't forget to set IFS back to a proper value):

$ arr=( {1..5} )    # Populate an array with brace expansion and compound assignment
$ IFS=','
$ echo "${arr[*]}"  # Reference all the items with the * subscript
1,2,3,4,5
3

If you allow for spaces along with commas, try

$ echo {1..5},
1, 2, 3, 4, 5,

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .