kniepbert kniepbert - 3 months ago 11x
Bash Question

Add item to comma separated list with one-liner

I want to add a new item to a string variable which represents a comma-separated list while preventing to have items twice.

I came up with this python solution:

python -c "import sys ; first = set(sys.argv[1].split(',')) ; all = first.union(set(sys.argv[2:])) ; print ','.join(all)" 1,2 4 3 2

In multiple lines:

import sys
first = set(sys.argv[1].split(','))
all = first.union(set(sys.argv[2:]))
print ','.join(all)

While the solution works, it is not pretty well suited for a one-liner in a shell script.

I've tried a couple of things using
or plain
but nothing lead to a short but still stable solution. Does anybody has an idea how to express that with a short command line idiom?

cxw cxw

A bash option: Keep your list of items in a string variable (list below) with leading and trailing commas. That way every item begins and ends with a comma, which makes things much easier. To add an item:

new_item=42   # or whatever

The ${list//...} removes any duplicates (// means global replacement), then the ${new_item}, pastes the new item onto the end of the list. To add multiple items:

for x in 4 3 2 ; do list="${list//,$x,/,}$x," ; done

To strip the commas off the list, you can use


A one-liner for your specific example above, but extended with more test cases, would be:

bash -c 'list=",$1,"; shift; for f in "$@"; do list="${list//,$f,/,}$f,"; done; list="${list#,}"; list="${list%,}"; echo $list' -- 1,2 3 4 44 444 1 2

Note, though, that most of that line is just getting the list from the arguments and then out to stdout. Inside a script, list="${list//,$x,/,}$x," is all you need.