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

为何Bash中该字符串拆分表达式无法生成数组?

Hey there! Let's break down why your original array expression wasn't working as expected, and go over the fixes you've already implemented (great job on that, by the way!).

What went wrong with the original code?

  1. read -a only processes a single line
    The read command, even with the -a flag, reads one line at a time and splits that line into array elements based on IFS. So when you fed it the multi-line output of iconv -l, it only grabbed the first line, leaving the rest unprocessed—hence your array only had the first element.

  2. Incorrect IFS setup
    IFS='\n' doesn't set the separator to a newline character. Inside single quotes, \n is treated as literal characters (a backslash followed by an 'n'), not a newline. To set IFS to a newline, you'd need IFS=$'\n' (using Bash's ANSI-C escape syntax). But even if you fixed this, read would still only handle one line, so this wasn't the core issue.

  3. Unquoted command substitution
    $(iconv -l) without double quotes lets Bash split the output of iconv -l into words using whitespace (spaces, newlines, tabs) as separators. Those words are then joined back into a single space-separated string for the here-string (<<<). This destroyed the original line structure, making it impossible to split into individual encodings correctly.

Why your modified code works

Your updated script uses readarray (a Bash 4.0+ command, also aliased as mapfile), which is purpose-built for reading multi-line input into an array—each line becomes an array element automatically. Here's what makes it work:

  • readarray -t possibleEncodings <<< "$(iconv -l)"
    • The -t flag trims the trailing newline from each line, so your array elements don't have extra whitespace at the end.
    • Wrapping $(iconv -l) in double quotes preserves the original line breaks from iconv -l, so readarray can correctly parse each encoding as its own element.
  • You switched to lowercase variable names (like possibleEncodings instead of POSSIBLE_ENCODINGS)—this is a great Bash best practice, since uppercase names are reserved for system environment variables.

A compatibility note (for older Bash versions)

If you're working with Bash <4.0 where readarray isn't available, you can use a while loop to build the array manually:

possibleEncodings=()
while IFS= read -r line; do
    possibleEncodings+=("$line")
done <<< "$(iconv -l)"

The IFS= ensures leading/trailing whitespace in lines is preserved, and -r prevents backslashes from being treated as escape characters.

Also, a small tweak for robustness: when trimming the encoding with sed, wrap $currentEncoding in double quotes to handle any encoding names that might contain spaces (unlikely with iconv, but it's a good habit):

trimmedEncoding=$(echo "$currentEncoding" | sed 's:/*$::')

内容的提问来源于stack exchange,提问作者ElToro1966

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:38:13