使用AWK命令实现两个制表符分隔文件的矩阵乘法
AWK实现两个制表符分隔文件的矩阵乘法
没问题,我来帮你搞定这个AWK矩阵乘法的需求!首先得明确矩阵的结构——你给出的文件内容是单行数字序列,我根据你期望的输出反推了正确的维度:
- 文件
m1是2行4列的矩阵,实际内容应该是(每行元素用制表符分隔):1 2 3 4 5 6 7 8 - 文件
m2是4行2列的矩阵,实际内容应该是:1 2 3 4 5 6 7 8
这样两者相乘才能得到你想要的2行2列结果:50 60和114 140。
下面是实现这个需求的AWK脚本,我会逐部分解释逻辑:
BEGIN { FS = "\t" } # 设置字段分隔符为制表符,匹配你的文件格式 # 读取第一个矩阵m1,存入二维数组a[i][j],i是行号,j是列号 FILENAME == ARGV[1] { for (j=1; j<=NF; j++) { a[NR][j] = $j } rows_m1 = NR # 记录m1的行数 cols_m1 = NF # 记录m1的列数 next # 跳过后续处理,直接读下一行 } # 读取第二个矩阵m2,存入二维数组b[j][k],j是行号,k是列号 FILENAME == ARGV[2] { for (k=1; k<=NF; k++) { b[NR][k] = $k } rows_m2 = NR # 记录m2的行数 cols_m2 = NF # 记录m2的列数 } # 矩阵核心计算与输出部分 END { # 先做合法性检查:第一个矩阵的列数必须等于第二个矩阵的行数,否则无法相乘 if (cols_m1 != rows_m2) { print "错误:第一个矩阵的列数必须等于第二个矩阵的行数!" > "/dev/stderr" exit 1 } # 遍历结果矩阵的每一行(对应m1的行) for (i=1; i<=rows_m1; i++) { # 遍历结果矩阵的每一列(对应m2的列) for (k=1; k<=cols_m2; k++) { c[i][k] = 0 # 累加计算:m1的第i行 × m2的第k列 for (j=1; j<=cols_m1; j++) { c[i][k] += a[i][j] * b[j][k] } # 格式化输出:最后一列后换行,其余列后加制表符 printf "%s%s", c[i][k], (k == cols_m2 ? "\n" : "\t") } } }
使用方法
- 把上面的脚本保存为
matrix_mult.awk - 确保你的
m1和m2文件是正确的制表符分隔格式(每行对应矩阵一行) - 运行命令:
awk -f matrix_mult.awk m1 m2
针对单行文件的适配
如果你的m1和m2确实是单行的数字序列(比如m1是1 2 3 4 5 6 7 8),那需要调整脚本的读取逻辑,手动拆分矩阵行:
修改m1的读取部分为:
FILENAME == ARGV[1] { rows_m1 = 2 # 手动指定m1的行数 cols_m1 = 4 # 手动指定m1的列数 idx = 1 for (i=1; i<=rows_m1; i++) { for (j=1; j<=cols_m1; j++) { a[i][j] = $(idx++) } } next }
修改m2的读取部分为:
FILENAME == ARGV[2] { rows_m2 = 4 # 手动指定m2的行数 cols_m2 = 2 # 手动指定m2的列数 idx = 1 for (j=1; j<=rows_m2; j++) { for (k=1; k<=cols_m2; k++) { b[j][k] = $(idx++) } } }
这样即使文件是单行的,也能正确拆分矩阵并计算。
运行调整后的脚本,就能得到你期望的输出:
50 60 114 140
内容的提问来源于stack exchange,提问作者Jake Steele
相关产品推荐
相关产品推荐

