Bash脚本转置文件时多维数组报错及尾空格去除问题
Bash脚本实现文件转置的问题解决
关于bad substitution错误的原因及解决
Bash不支持原生的多维数组,你写的${parent_array[$i][$j]}这种语法是无效的,这就是报错的根源。要在Bash里模拟多维数组的效果,常用两种思路:
- 拆分每行到独立数组:把文件的每一行分别存为一个一维数组(比如
row0、row1),然后通过间接引用访问指定位置的元素。 - 一维数组+索引计算:假设原文件有
cols列,那么原第i行第j列的元素,在一维数组中的索引是i*cols + j,通过计算索引来访问。
如何去除输出末尾的多余空格
直接用循环拼接字符串或逐个输出元素时,很容易在末尾留下空格。推荐两种可靠的解决方法:
- 数组+分段printf输出:先把当前行的所有元素存到数组里,先输出第一个元素,再对剩下的元素逐个输出「空格+元素」,最后换行。
- 参数扩展去除尾空格:如果已经拼接好带尾空格的字符串,可以用
${str% }去掉最后一个空格(注意%后面是空格)。
完整的转置脚本示例
下面是能正确实现转置且无尾空格的Bash脚本:
#!/bin/bash # 读取file.txt的每一行到rows数组 rows=() while IFS= read -r line; do rows+=("$line") done < file.txt # 获取原文件的列数(通过第一行拆分后的元素个数) IFS=' ' read -r -a first_row <<< "${rows[0]}" total_cols=${#first_row[@]} # 获取原文件的行数 total_rows=${#rows[@]} # 循环遍历每一列,生成转置后的行 for ((col_idx=0; col_idx<total_cols; col_idx++)); do current_line=() # 收集当前列的所有元素 for ((row_idx=0; row_idx<total_rows; row_idx++)); do IFS=' ' read -r -a current_row <<< "${rows[row_idx]}" current_line+=("${current_row[col_idx]}") done # 输出当前行,避免尾空格 printf "%s" "${current_line[0]}" for elem in "${current_line[@]:1}"; do printf " %s" "$elem" done echo done
脚本说明
- 先把文件所有行读入
rows数组,确保每行的原始内容被保留。 - 通过拆分第一行得到原文件的列数,转置后的行数等于原列数。
- 外层循环处理每一列,内层循环收集该列的所有元素到
current_line数组。 - 用
printf分段输出:先输出第一个元素,再依次输出带空格的后续元素,完美避免尾空格。
内容的提问来源于stack exchange,提问作者suresh
相关产品推荐
相关产品推荐

