Bash Shell脚本CSV处理-使用AWK添加新列

Bash Shell脚本CSV处理-使用AWK添加新列,bash,shell,csv,awk,Bash,Shell,Csv,Awk,我有一个处理CSV文件的shell脚本。一个特别的步骤是添加一个列并在其中放入默认值“null”。我得到了预期的更改,只是要添加的新列被添加到下一行,而不是同一行 有人能指出代码中的错误并导致这种意外的更改吗 代码: 输入CSV: OldColm1,OldColm2,OldColm3,OldColm4,OldColm5,OldColm6 Value1,Value2,Value3,Value4,Value5,Value6 输出CSV: OldColm1;OldColm2;OldColm3;Old

我有一个处理CSV文件的shell脚本。一个特别的步骤是添加一个列并在其中放入默认值“null”。我得到了预期的更改,只是要添加的新列被添加到下一行,而不是同一行

有人能指出代码中的错误并导致这种意外的更改吗

代码:

输入CSV:

OldColm1,OldColm2,OldColm3,OldColm4,OldColm5,OldColm6
Value1,Value2,Value3,Value4,Value5,Value6
输出CSV:

OldColm1;OldColm2;OldColm3;OldColm4;OldColm5;OldColm6
;NewColm
Value1;Value2;Value3;Value4;Value5;Value6
;NULL
预期CSV:

OldColm1;OldColm2;OldColm3;OldColm4;OldColm5;OldColm6;NewColm
Value1;Value2;Value3;Value4;Value5;Value6;NULL

如注释中所述,这是由于行之间用
\r\n
而不是
\n
分隔所致

od
程序可用于说明这一点:

cat源代码\u dos.csv
OldColm1、OldColm2、OldColm3、OldColm4、OldColm5、OldColm6
值1、值2、值3、值4、值5、值6
od-c源代码\u dos.csv
0000000OLDCOLM 1,OLDCOLM
0000020 2,O l d C O l m 3,O l d C O
0000040升M4,O l d C O l m 5,O l d
0000060 C o l m 6\r\n V a l u e 1,V a
0000100L u e 2,V a l u e 3,V a l u
0000120 e 4,V a l u e 5,V a l u e 6
00001440\r\n
0000142
awk'开始{FS=“,”OFS=“;”}
{$(NF+1)=NR==1?“NewColm”:“NULL”}
1.
'source_dos.csv
;纽科姆;OldColm2;OldColm3;OldColm4;OldColm5;OldColm6
;空1;价值2;价值3;价值4;价值5;价值6
awk'开始{FS=“,”OFS=“;”}
{$(NF+1)=NR==1?“NewColm”:“NULL”}
1.
'source_dos.csv | od-c
0000000OLdCOMLM1;O l d C O l m
0000020   2   ;   O l d C O l m 3;O l d C O
0000040升4米;O l d C O l m 5;奥利德
0000060立方英尺6米\r;N e w C o l m\N V
0000100ALUE1;V a l u e 2;V a l
0000120UE3;V a l u e 4;V a l u e
0000140   5   ;   V a l u e 6\r;N U L L\N
0000157
注释中提供的解决方案是将输入从类
DOS
-like(
\r
)转换为类
UNIX
-like(
\n
)输入:

cp source\u dos.csv source\u unix.csv&&dos2unix source\u unix.csv
dos2unix:将文件源_unix.csv转换为unix格式。。。
od-c source_unix.csv
0000000OLDCOLM 1,OLDCOLM
0000020 2,O l d C O l m 3,O l d C O
0000040升M4,O l d C O l m 5,O l d
0000060 C o l m 6\n V a l u e 1,V a l
0000100U e 2,V a l u e 3,V a l u e
00001204,V a l u e 5,V a l u e 6\n
0000140
awk'开始{FS=“,”OFS=“;”}
{$(NF+1)=NR==1?“NewColm”:“NULL”}
1.
'source_unix.csv
OldColm1;OldColm2;OldColm3;OldColm4;OldColm5;OldColm6;纽科姆
价值1;价值2;价值3;价值4;价值5;价值6;无效的
awk'开始{FS=“,”OFS=“;”}
{$(NF+1)=NR==1?“NewColm”:“NULL”}
1.
'source_unix.csv | od-c
0000000OLdCOMLM1;O l d C O l m
0000020   2   ;   O l d C O l m 3;O l d C O
0000040升4米;O l d C O l m 5;奥利德
0000060立方英尺6米;N e w C o l m\N V a
0000100L u e 1;V a l u e 2;V a l u
0000120e3;V a l u e 4;V a l u e 5
0000140   ;   V a l u e 6;N U L L\N
0000155
一个
awk
——处理这个问题的唯一解决方案是相应地调整记录分隔符
RS

RS
,以及其对应的输出记录分隔符
ORS
,默认为
\n
。 这就是为什么在
\r\n
输入案例中,
\r
仍然是最后一个输入列的一部分,而您的新列“卡”在这
\r
和添加为
OR
\n
之间

更改
RS
可解决此问题:

awk'BEGIN{RS=“\r\n”FS=“,”OFS=“;”}
{$(NF+1)=NR==1?“NewColm”:“NULL”}
1.
'source_dos.csv
OldColm1;OldColm2;OldColm3;OldColm4;OldColm5;OldColm6;纽科姆
价值1;价值2;价值3;价值4;价值5;价值6;无效的
请注意,这仍将创建类(
\n
)输出:

awk'BEGIN{RS=“\r\n”FS=“,”OFS=“;”}
{$(NF+1)=NR==1?“NewColm”:“NULL”}
1.
'source_dos.csv | od-c
0000000OLdCOMLM1;O l d C O l m
0000020   2   ;   O l d C O l m 3;O l d C O
0000040升4米;O l d C O l m 5;奥利德
0000060立方英尺6米;N e w C o l m\N V a
0000100L u e 1;V a l u e 2;V a l u
0000120e3;V a l u e 4;V a l u e 5
0000140   ;   V a l u e 6;N U L L\N
0000155
要生成类似(
\r\n
)输出的
DOS
,也只需调整
ORS

awk'BEGIN{RS=“\r\n”ORS=RS;FS=“,”OFS=“;”}
{$(NF+1)=NR==1?“NewColm”:“NULL”}
1.
'source_dos.csv
OldColm1;OldColm2;OldColm3;OldColm4;OldColm5;OldColm6;纽科姆
价值1;价值2;价值3;价值4;价值5;价值6;无效的
awk'BEGIN{RS=“\r\n”ORS=RS;FS=“,”OFS=“;”}
{$(NF+1)=NR==1?“NewColm”:“NULL”}
1.
'source_dos.csv | od-c
0000000OLdCOMLM1;O l d C O l m
0000020   2   ;   O l d C O l m 3;
OldColm1;OldColm2;OldColm3;OldColm4;OldColm5;OldColm6;NewColm
Value1;Value2;Value3;Value4;Value5;Value6;NULL