如何使用awk使用另一个csv文件的映射更新csv文件中的一列

时间:2017-03-02 12:19:06

标签: shell unix awk

我需要帮助更新一个包含350万条记录的巨大csv文件。我需要使用另一个文件中的映射值更新第3列。

我尝试通过搜索映射文件中的模式来读取文件并更新第3列,但由于实际文件有350万,而映射文件有大约100万条记录,所以它似乎永远在运行。

E.g。

实际档案:

123,123abc,456_def,456_def_ble,adsf,adsafdsa,123234,45645,435,12,42,afda,3435,wfg,34,345,sergf,5t4
234,234abc,5435_defg,345_def_ble,3adsaff,asdfgdsa,165434,456,435,12,42,afda,3435,wfg,34,345,sergf,5t4

映射文件:

456_def,24_def
5435_defg,48_defg

预期输出:

123,123abc,24_def,456_def_ble,adsf,adsafdsa,123234,45645,435,12,42,afda,3435,wfg,34,345,sergf,5t4
234,234abc,48_defg,345_def_ble,3adsaff,asdfgdsa,165434,456,435,12,42,afda,3435,wfg,34,345,sergf,5t4

2 个答案:

答案 0 :(得分:2)

Awk

中非常简单
awk 'BEGIN{FS=OFS=","}FNR==NR{hash[$1]=$2; next}$3 in hash{$3=hash[$3]}1' mapFile actualFile

根据需要生成输出。

123,123abc,24_def,456_def_ble,adsf,adsafdsa,123234,45645,435,12,42,afda,3435,wfg,34,345,sergf,5t4
234,234abc,48_defg,345_def_ble,3adsaff,asdfgdsa,165434,456,435,12,42,afda,3435,wfg,34,345,sergf,5t4

为了加快速度,您可以将locale设置更改为使用ASCII

简单地说,当使用locale C时,它将默认为服务器的基础Unix / Linux语言ASCII。默认情况下,您的语言环境将被国际化并设置为UTF-8,它可以表示Unicode字符集中的每个字符,以帮助显示当前超过110,000个唯一字符的任何世界编写系统,而对于ASCII,每个字符都以单字节序列编码,其字符集包含不超过128个唯一字符。所以就这样做

LC_ALL=C awk 'BEGIN{FS=OFS=","}FNR==NR{hash[$1]=$2; next}$3 in hash{$3=hash[$3]}1' mapFile actualFile

答案 1 :(得分:0)

您可以使用awk

awk 'BEGIN{FS=OFS=","}       # Set field separator as comma
     NR==FNR{a[$1]=$2;next}  # Store the mapping file into the array a
     {if($3 in a) $3=a[$3]}  # Check if there is match, and change the column value
     1                       # Print the whole line
    ' mapping actualfile