使用分隔符连接字符串的可移植 UNIX 方法

使用分隔符连接字符串的可移植 UNIX 方法

是否有一种可移植的 unix shellscripting 方法可以将多个字符串用给定的分隔符连接在一起,如下所示:

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

当然,我可以使用 $scripting_language 单行代码或 shellscript 函数中丑陋的显式循环,但旧时的 unix 黑客可能也需要这样做,所以有人在过去的某个地方制作了这样的标准命令,而我不知道,对吗?

编辑

在许多情况下,该sed方法无疑是最简单的方法,但如果字符串可以包含空格,则该方法不起作用。而且许多其他答案也没有处理这个问题。除了这个$IFS技巧之外,还有其他解决方案可以处理空格(以及所有可能的字符)并且不需要编写完整的循环吗?

答案1

对于多字符的长分隔符,可以使用:

  • sed(正如已经指出的那样@标记

      $ 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(但它会显示额外的结束分隔符)

      $ printf "%s---" foo bar baz quux
    

对于单字符长的分隔符,您可以:

  • 使用以下 shell 函数(按照这个所以帖子):

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

    用法:

      $ join_by '-' foo bar baz quux
    
  • 使用tr

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

答案2

我发现的最好的方法就是你提到的丑陋的显式循环。

join(){
    # If no arguments, do nothing.
    # This avoids confusing errors in some shells.
    if [ $# -eq 0 ]; then
        return
    fi

    local joiner="$1"
    shift

    while [ $# -gt 1 ]; do
        printf "%s%s" "$1" "$joiner"
        shift
    done

    printf '%s\n' "$1"
}

用法:

$ join --- foo bar baz quux
foo---bar---baz---quux

在 Ubuntu 上使用 Bash、Dash 和 Zsh 进行了测试,并且应该可以在其他基于 Bourne 的 shell 中使用。

答案3

Perl 不是简单操作复杂:

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

答案4

除了@embobo的评论(希望很快就能得到答案)之外,perl还可以用来分裂加入任意字符串。这比使用更复杂sed,并且根据上述示例,这将是一次重大的矫枉过正。

相关内容