AWK技术问题:基于File1每行批量修改全量File2生成对应文件
Fix: Make AWK Read Entire File2.txt for Each Line in File1.txt
嘿,我看到你的问题了——你写的awk脚本能生成正确的文件夹结构,但每个Fx.txt里只有一行内容,对吧?核心原因是你只调用了一次getline读取File2.txt,没循环读完所有行。我给你整理了修正后的脚本,还有详细的解释:
修正后的完整脚本(script.sh)
BEGIN { FS = "," # 先把File2的所有内容预读到数组里,避免重复打开文件,提升效率 while (getline line < "File2.txt") { file2_lines[++line_count] = line } close("File2.txt") } # 跳过表头行(只处理以F开头的行) $1 !~ /^F/ { next } { # 提取字段并去除前后空格(原数据是逗号+空格分隔,需要清理) LSmall = $2; gsub(/^[[:space:]]+|[[:space:]]+$/, "", LSmall) Roman = $3; gsub(/^[[:space:]]+|[[:space:]]+$/, "", Roman) LCaps = $4; gsub(/^[[:space:]]+|[[:space:]]+$/, "", LCaps) dir_name = $1 output_file = dir_name "/" dir_name ".txt" # 创建文件夹(-p参数避免已存在时报错) system("mkdir -p " dir_name) # 循环处理File2的每一行,生成修改后的内容 for (i=1; i<=line_count; i++) { current_line = file2_lines[i] # 根据关键词替换对应的内容 if (current_line ~ /Roman/) { gsub("here", Roman, current_line) } else if (current_line ~ /LSmall/) { gsub("here", LSmall, current_line) } else if (current_line ~ /LCaps/) { gsub("here", LCaps, current_line) } # 写入输出文件 print current_line > output_file } # 关闭文件,避免过多打开句柄 close(output_file) }
为什么原脚本只生成一行?
你的原代码在处理每个F开头的行时,只执行了一次getline < "File2.txt"——这只会读取File2的第一行,处理后就没有后续的读取操作了,所以每个Fx.txt里只有一行内容。要处理完整的File2,必须用循环读取所有行直到文件结束。
关键优化点说明
- 预读取File2到数组:把File2的内容提前存到数组里,不用每次处理File1的行都重新打开读取,效率更高,尤其适合大文件场景。
- 清理字段空格:原File1的字段是
逗号+空格分隔(比如F0, a, I, A),提取后用gsub去掉前后空格,避免替换时带多余空格。 - 健壮的文件夹创建:用
mkdir -p,即使文件夹已存在也不会报错。 - 关闭文件句柄:处理完每个输出文件后关闭,避免awk打开过多文件导致异常。
- 简洁的表头跳过逻辑:用
$1 !~ /^F/ { next }直接跳过非F开头的行,比原条件判断更清晰。
测试效果
运行这个脚本后,每个Fx.txt都会包含File2的完整内容,并且正确替换关键词。比如F0/F0.txt的内容会是:
Lorem ipsum Roman I. LCaps A. LSmall a. Lorem ipsum
内容的提问来源于stack exchange,提问作者massisenergy
相关产品推荐
相关产品推荐

