portable unix way to join strings with separator

19,523

Solution 1

For multi-character long separator, you can use:

  • sed (as already pointed by @Mark)

    $ echo foo bar baz quux | sed "s/ /---/g"
    
  • ex

    $ echo foo bar baz quux | ex +"s/ /---/gp" -cq! /dev/stdin
    $ ex +"s/ /---/gp" -scq! <(echo foo bar baz quux)
    
  • printf (but it will show the extra ending separator)

    $ printf "%s---" foo bar baz quux
    
  • using the following shell function (as per this SO post):

    join_by { local IFS="$1"; shift; echo "$*"; }
    

    Usage:

    $ join_by '---' foo bar baz quux
    

For one-character long separators, you can use:

  • tr

    echo foo bar baz quux | tr ' ' '-'
    

Solution 2

Perl is not that complex for simple operations:

$ perl -e 's/ /---/g'

Solution 3

lam

Here is the example using lam command:

$ SEP="---"; lam <(echo foo) -s$SEP <(echo bar) -s$SEP <(echo baz) -s$SEP <(echo quux)
foo---bar---baz---quux

paste

If the separator is one character long, then paste command can be used:

$ printf "%s\n" foo bar baz quux | paste -sd-
foo-bar-baz-quux
Share:
19,523

Related videos on Youtube

JanKanis
Author by

JanKanis

Updated on September 18, 2022

Comments

  • JanKanis
    JanKanis almost 2 years

    Is there a portable unix shellscripting way of joining a number of strings together with a given separator, like so:

    $ strjoin --- foo bar baz quux
    foo---bar---baz---quux
    

    Sure I could use a $scripting_language one liner or an ugly explicit loop in a shellscript function, but the unix hackers of old probably had some need for this as well, so someone has made a standard command like this that I don't know about somewhere in the past, right?

    edit

    The sed method is certainly the easiest one in many situations, but it doesn't work if the strings can contain spaces. And many of the other answers also don't handle that. Are there any solutions other than the $IFS trick that handle spaces (and all possible characters in general) and do not require writing a full loop?

    • MastaJeet
      MastaJeet almost 13 years
      sed 's/ /---/g' Why would you need a separate utility?
  • derobert
    derobert almost 13 years
    Considering OP wants to join parameters, that'd be perl -E 'say join(shift, @ARGV)' -- delim str1 str2 str3 ... The perl one-liner you've posted doesn't actually do anything (well, it changes $_, but that isn't passed into or out of the one liner). You probably wanted to pass -p as well.
  • Mu Mind
    Mu Mind over 5 years
    The IFS solution doesn't actually work for a multiple character delimiter, just takes the first character as delimiter and ignores the rest: join_by '---' foo bar baz quuxfoo-bar-baz-quuz
  • ssc
    ssc over 3 years
    This seems to work with GNU paste on Linux; on macOS, either install GNU tools (e.g. using brew ls coreutils) and use as gpaste or work with BSD paste and append an additional - to explicitly specify standard input as input file: printf "%s\n" foo bar baz quux | paste -sd- -