我对 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