使用awk在CSV文件首列前插入自定义列的技术问题
用AWK给CSV第一列前插入带自定义逐行值的新列
问题场景
需要给CSV文件的第一列前插入一列,且新列的每行值为指定自定义内容,原始CSV内容如下:
A,B,C,D,E,F 1,2,3,4,5,6 2,3,4,5,6,7 3,4,5,6,7,8 4,5,6,7,8,9
此前尝试的AWK代码无法实现自定义逐行值,代码如下:
BEGIN{FS=OFS=","}{$1=$1 OFS (FNR<1 ? $1 "0\nA\n2\nC" : "col")}1
得到的结果所有新列值均为col,不符合预期:
A,col,B,C,D,E,F 1,col,2,3,4,5,6 2,col,3,4,5,6,7 3,col,4,5,6,7,8 4,col,5,6,7,8,9
期望结果为新列每行使用指定自定义值:
col,A,B,C,D,E,F 0,1,2,3,4,5,6 A,2,3,4,5,6,7 2,3,4,5,6,7,8 C,4,5,6,7,8,9
解决方案
可以通过在AWK中预先定义存储自定义值的数组,结合行号(FNR)匹配对应值来实现:
方法1:直接在代码中定义自定义值数组
BEGIN { FS = OFS = "," # 按行号顺序定义新列值,索引对应行号FNR new_vals[1] = "col" new_vals[2] = "0" new_vals[3] = "A" new_vals[4] = "2" new_vals[5] = "C" } { # 将新列值拼在原行最前面 $0 = new_vals[FNR] OFS $0 } 1
方法2:通过here-doc传递自定义值(适合值较多的场景)
如果自定义值数量多,可通过here-doc传入值,避免代码中写大量数组赋值:
BEGIN { FS = OFS = "," # 读取标准输入的自定义值到数组 while (getline val < "/dev/stdin") { new_vals[++cnt] = val } } { $0 = new_vals[FNR] OFS $0 } 1
执行时传入自定义值:
awk -f script.awk <<EOF col 0 A 2 C EOF input.csv
结果验证
执行上述任意方法后,输出结果将与期望完全一致:
col,A,B,C,D,E,F 0,1,2,3,4,5,6 A,2,3,4,5,6,7 2,3,4,5,6,7,8 C,4,5,6,7,8,9
原理解释
FNR是AWK内置变量,表示当前处理的行号(从1开始),正好对应自定义值的顺序;- 预先将每行需要的新列值存入数组
new_vals,处理每行时直接取对应索引的值拼在原行前即可; - 此前代码错误在于
FNR<1的条件永远不成立(行号从1开始),导致所有行都使用col作为新列值。
内容的提问来源于stack exchange,提问作者arnpry
相关产品推荐
相关产品推荐

