You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写支持任意输入与分隔符的纯Bash字符串分割函数

纯Bash通用字符串分割函数实现

需求说明

开发纯Bash函数实现字符串分割功能,支持接收任意字符串作为输入内容与分隔符,兼容最新版本的Debian、Ubuntu(服务器/桌面版)、Arch、RedHat、CentOS、SUSE(服务器/桌面版)。现有多数Bash字符串分割方案仅适用于特定场景,无法覆盖复杂分隔符(如含正则特殊字符、转义字符、引号等)的通用需求。

实现代码

f_my_answer() {
    local input_str="$1"
    local delimiter="$2"
    local escaped_delim

    # 对分隔符中的正则特殊字符进行转义,确保精确匹配
    escaped_delim=$(printf '%s' "$delimiter" | awk '{gsub(/[.*+?^${}()|[\]\\]/, "\\\\&"); print}')

    # 通过awk按分隔符分割字符串,以空字符作为输出分隔符,再用readarray读取到数组
    readarray -td '' split_result < <(awk -v delim="$escaped_delim" '{
        while (match($0, delim)) {
            print substr($0, 1, RSTART-1) "\0"
            $0 = substr($0, RSTART+RLENGTH)
        }
        print $0 "\0"
    }' <<< "$input_str")

    # 格式化输出分割结果
    printf '=== 分隔符:%q ===\n' "$delimiter"
    for idx in "${!split_result[@]}"; do
        printf '第%d段:%q\n' "$((idx+1))" "${split_result[$idx]}"
    done
    echo
}

测试用例

以下是用于验证函数兼容性的测试代码,包含复杂输入内容与各类特殊分隔符:

read -r -d '' FILE_CONTENT << 'HEREDOC'
BEGIN

§\\§[+][.][-]
A literal backslash, ‘\’.°

°\a
The “alert” character, Ctrl-g, ASCII code 7 (BEL). (This often makes some sort of audible noise.)

\b
Backspace, Ctrl-h, ASCII code 8 (BS).

\f
Formfeed, Ctrl-l, ASCII code 12 (FF).

\n
Newline, Ctrl-j, ASCII code 10 (LF).

\r
Carriage return, Ctrl-m, ASCII code 13 (CR).

\t
Horizontal TAB, Ctrl-i, ASCII code 9 (HT).

\v
Vertical TAB, Ctrl-k, ASCII code 11 (VT).-

\nnn
The octal value nnn, where nnn stands for 1 to 3 digits between ‘0’ and ‘7’. For example, the code for the ASCII ESC (escape) character is ‘\033’.


15

It may also be helpful to note (though understandably you had no room to do so) that the -d option to readarray first appears in Bash 4.4. – 
fbicknel
 Aug 18, 2017 at 15:57
4

Great answer (+1). If you change your awk to awk '{ gsub(/,[ ]+|$/,"\0"); print }' ./  and eliminate that concatenation of the final ", " then you don't have to go through the gymnastics on eliminating the final record. So: readarray -td '' a < <(awk '{ gsub(/,[ ]+/,"\0"); print; }' <<<"$string") on Bash that supports readarray. Note your method is Bash 4.4+ I think because of the -d in readarray – 
dawg
 Nov 26, 2017 at 22:28 
10

Wow, what a brilliant answer! Hee hee, my response: ditched the bash script and fired up python! – 
artfulrobot
 May 14, 2018 at 11:32
11

I'd move your right answers up to the top, I had to scroll through a lot of rubbish to find out how to do it properly :-) – 
paxdiablo
 Jan 9, 2020 at 12:31
44

This is exactly the kind of thing that will convince you to never code in bash. An astoundingly simple task that has 8 incorrect solutions. Btw, this is without a design constraint of, "Make it as obscure and finicky as possible"§$
END
HEREDOC
F_MS_STR_TO_SPLIT="${FILE_CONTENT:6:-3}"
F_MS_DELIMITER_P="int }' ./  and eliminate"
f_my_answer "$F_MS_STR_TO_SPLIT" "$F_MS_DELIMITER_P"
f_my_answer "$F_MS_STR_TO_SPLIT" "."
f_my_answer "$F_MS_STR_TO_SPLIT" "+"
f_my_answer "$F_MS_STR_TO_SPLIT" "'"
f_my_answer "$F_MS_STR_TO_SPLIT" "\\"
f_my_answer "$F_MS_STR_TO_SPLIT" "-"
f_my_answer "a.+b.+c" "[.][+]"
f_my_answer "a[.][+]b[.][+]c" "[.][+]"
f_my_answer "a.+b.+c" ".+"

兼容性说明

该函数依赖Bash 4.4及以上版本的readarray -d特性,而指定的所有发行版最新版本均已预装符合要求的Bash版本,无需额外安装依赖。

内容的提问来源于stack exchange,提问作者Eduardo Lúcio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:54:21