如何在 CSV 文件中追加新行并在 Unix 中修改它们

如何在 CSV 文件中追加新行并在 Unix 中修改它们

我对 Unix 总体来说是个新手,并开始学习 shell 脚本。我正在使用包含以下示例行的 CSV 文件(这是一个大型 CSV 文件,每个项目有 4 个条目):

Table 1
Item ID   Time                  Available   Location 
0001      02/02/2021  08:00     Y           NJ
0001      02/02/2021  09:00     N           UT
0001      02/02/2021  10:00     Y           AZ
0001      02/02/2021  11:00     Y           CA
0002      02/02/2021  08:00     Y           NJ
0002      02/02/2021  09:00     N           UT
0002      02/02/2021  10:00     Y           AZ
0002      02/02/2021  11:00     Y           CA      

我有另一个 CSV,其中包含一堆项目 ID,如下所示:

Table 2
Item ID   Item_Name   Item_Aux_ID    Item_Aux_name
1001      IT_1        3323           IT_Aux_1
1002      IT_2        3325           IT_Aux_2
1003      IT_3        3328           IT_Aux_3
1010      IT_4        3333           IT_Aux_4

我想在第一个 CSV 文件中创建新条目(第二个 CSV 文件中的每个项目一个条目)。每个新条目应与 Table1 的第一行相同,并适当替换项目 ID。预期输出为:

Table 1
Item ID   Time                  Available   Location 
0001      02/02/2021  08:00     Y           NJ
0001      02/02/2021  09:00     N           UT
0001      02/02/2021  10:00     Y           AZ
0001      02/02/2021  11:00     Y           CA
0002      02/02/2021  08:00     Y           NJ
0002      02/02/2021  09:00     N           UT
0002      02/02/2021  10:00     Y           AZ
0002      02/02/2021  11:00     Y           CA  
1001      02/02/2021  08:00     Y           NJ
1002      02/02/2021  08:00     Y           NJ
1003      02/02/2021  08:00     Y           NJ
1010      02/02/2021  08:00     Y           NJ 

如何在 Unix 中编写脚本来实现上述功能?提前致谢。

答案1

尝试这个;阅读评论以了解逻辑

awk '
NR==2           {SV = $0                # save the relevant info from file1
                 RG = $1
                }
NR != FNR       {if (FNR==1) next       # in new file: skip header
                 sub(RG, $1, SV)        # insert new "item ID" in saved line
                 RG = $1                # save new search pattern
                 sub($0, SV)            # replace input line with modified saved line   
                }
1                                       # print it
' file[12] 
Item ID   Time                  Available   Location 
0001      02/02/2021  08:00     Y           NJ
0001      02/02/2021  09:00     N           UT
0001      02/02/2021  10:00     Y           AZ
0001      02/02/2021  11:00     Y           CA
0002      02/02/2021  08:00     Y           NJ
0002      02/02/2021  09:00     N           UT
0002      02/02/2021  10:00     Y           AZ
0002      02/02/2021  11:00     Y           CA
1001      02/02/2021  08:00     Y           NJ
1002      02/02/2021  08:00     Y           NJ
1003      02/02/2021  08:00     Y           NJ
1010      02/02/2021  08:00     Y           NJ

答案2

我强烈建议您尽可能使用支持 CSV 的工具来处理 CSV 文件。该 awk 脚本适用于非常简单(“普通”)的 CSV,但如果您的 CSV 有引号,则在 awk 中解析就会出现问题。

GoCSV是一个支持 CSV 的工具,它具有许多命令,可以让您对数据进行大量控制,而无需编写命令式代码。您将所需的内容声明为一系列步骤(可以流水线化):

#!/bin/sh

# Isolate 1st row from table1
gocsv head -n 1 table1.csv > first_row.csv

# Add a shared key to first_row and table2 (in the new column 'Key')
gocsv add -n Key -t '_key_' first_row.csv > first_row_keyed.csv

gocsv add -n Key -t '_key_' table2.csv > table2_keyed.csv

# Left-join first_row to table2, by matching on the shared key (the Key column)
gocsv join -c Key table2_keyed.csv first_row_keyed.csv > table2_joined.csv

# Select (cut) the first 'Item ID' (column 1) and the other 3 fields that were joined from first_row
gocsv select -c 1,'Time','Available','Location' table2_joined.csv > table2_cut.csv

# Stack table1 then new version of table2
gocsv stack table1.csv table2_cut.csv > final.csv

我模拟了你的样本数据:

表格1

Item ID,Time,Available,Location
0001,02/02/2021  08:00,Y,NJ
0001,02/02/2021  09:00,N,UT
0001,02/02/2021  10:00,Y,AZ
0001,02/02/2021  11:00,Y,CA
0002,02/02/2021  08:00,Y,NJ
0002,02/02/2021  09:00,N,UT
0002,02/02/2021  10:00,Y,AZ
0002,02/02/2021  11:00,Y,CA

表2

Item ID,Item_Name,Item_Aux_ID,Item_Aux_name
1001,IT_1,3323,IT_Aux_1
1002,IT_2,3325,IT_Aux_2
1003,IT_3,3328,IT_Aux_3
1010,IT_4,3333,IT_Aux_4

当我在这两个文件上运行该脚本时,我得到了这个最终.csv

Item ID,Time,Available,Location
0001,02/02/2021  08:00,Y,NJ
0001,02/02/2021  09:00,N,UT
0001,02/02/2021  10:00,Y,AZ
0001,02/02/2021  11:00,Y,CA
0002,02/02/2021  08:00,Y,NJ
0002,02/02/2021  09:00,N,UT
0002,02/02/2021  10:00,Y,AZ
0002,02/02/2021  11:00,Y,CA
1001,02/02/2021  08:00,Y,NJ
1002,02/02/2021  08:00,Y,NJ
1003,02/02/2021  08:00,Y,NJ
1010,02/02/2021  08:00,Y,NJ

相关内容