JCL中使用SORT实现双文件字段覆盖的问题求助
无公共键字段覆盖实现方案
默认前提:两个文件按行一一对应覆盖,即F1的第N行对应修改F2的第N行指定字段,两个文件行数一致。如果F1只有1行需要覆盖所有F2行可参考文末补充说明。
方案1:awk命令(适用于本地小文本文件)
假设字段分隔符为制表符\t,需要用F1的4个字段分别替换F2的第2、5、7、10位字段,可根据实际需求修改分隔符和目标字段位置:
awk 'BEGIN{FS=OFS="\t"} NR==FNR{f1[NR]=$0;next} {split(f1[FNR],a); $2=a[1];$5=a[2];$7=a[3];$10=a[4]; print}' F1 F2 > output_file
参数说明:
FS=OFS="\t":指定输入输出字段分隔符,逗号分隔可替换为,- 先读取F1所有行按行号存入数组,再逐行读取F2替换指定字段后输出,保留F2其余字段原值
方案2:Spark DataFrame(适用于分布式大数据场景)
此前overlay未生效是因为缺少行对齐关联步骤,正确实现逻辑如下:
- 给两个DataFrame添加统一行号,按行号关联
- 替换指定字段后保留F2的全字段结构
示例代码(Scala):
import org.apache.spark.sql.functions.{row_number, lit} import org.apache.spark.sql.expressions.Window // 读取两个表并添加行号 val df1WithRow = df1.withColumn("row_id", row_number().over(Window.orderBy(lit(1)))) val df2WithRow = df2.withColumn("row_id", row_number().over(Window.orderBy(lit(1)))) // 关联后替换指定字段,保留F2所有列 val res = df2WithRow.join(df1WithRow, Seq("row_id"), "left") .select( col("f1"), col("col1").alias("f2"), // 替换F2的f2为F1的col1 col("f3"), col("f4"), col("col2").alias("f5"), // 替换F2的f5为F1的col2 col("f6"), col("col3").alias("f7"), // 替换F2的f7为F1的col3 col("f8"), col("f9"), col("col4").alias("f10"), // 替换F2的f10为F1的col4 col("f11"), col("f12"), col("f13"), col("f14") ).drop("row_id")
补充:如果F1只有1行需要覆盖所有F2的行,awk命令中把
f1[FNR]改为f1[1]即可;Spark场景下将df1单行广播后直接关联即可。
内容的提问来源于stack exchange,提问作者siva
相关产品推荐
相关产品推荐

