在 csv 文件中查找匹配项

在 csv 文件中查找匹配项

我有两个 CSV 文件。

1.csv包含:

46700468915;2000

2.csv包含:

4670046;Tele2

我尝试从 2.csv 中搜索 4670046 是否存在于 1.csv 中,然后从 2.csv 中取出 Tele2 并添加到 1.csv 中,如果没有匹配则不添加

awk 'NR==FNR {a[$1]=$2; next} $2 in a {print $0, a[$2]}' OFS='\t' 2.csv 1.csv

答案1

这里有几个问题:

  1. 您需要适当地设置 awk 的字段分隔符:默认情况下它是空格,而您的文件似乎由分号分隔

  2. 你正尝试匹配部分字段:4670046a46700468915不在

  3. 您似乎对要匹配的字段感到困惑,$1或者$2

如果你知道要匹配前 7 个字符,你可以尝试

awk -F ';' '
  NR==FNR {a[$1]=$2; next} {k = substr($1,1,7)} k in a {print $0, a[k]}
' OFS='\t' 2.csv 1.csv

或者等价地

awk '
  BEGIN{FS=";"; OFS="\t"} 
  NR==FNR {a[$1]=$2; next} {k = substr($1,1,7)} k in a {print $0, a[k]}
' 2.csv 1.csv

例如给定

$ head ?.csv
==> 1.csv <==
46700468915;2000

==> 2.csv <==
4670046;Tele2

然后

$ awk 'BEGIN{FS=";"; OFS="\t"} NR==FNR {a[$1]=$2; next} {k = substr($1,1,7)} k in a {print $0, a[k]}' 2.csv 1.csv
46700468915;2000    Tele2

答案2

解决方案awk应该更快,但这里有一个例子,如何通过bash脚本实现这一点,read其中每一行2.csv作为-array 然后用来sed做更改(该if语句不是脚本的必要部分)。

$ cat ./script.sh
#!/bin/bash

TARGET_FILE="./1.csv"
ORIGIN_FILE="./2.csv"

# In order to append new column to a line, comment-out -i.bak
while IFS=';' read -r -a line
do
        if grep -q "${line[0]}" "$TARGET_FILE"
        then
                sed "/^${line[0]}/ s/$/;${line[1]}/" "$TARGET_FILE" #-i.bak
        fi
done < "$ORIGIN_FILE"

echo '-----'

# In order to replace the second column of a line, comment-out -i.bak
while IFS=';' read -r -a line
do
        if grep -q "${line[0]}" "$TARGET_FILE"
        then
                sed -r "s/(^${line[0]}.*\;).*$/\1${line[1]}/" "$TARGET_FILE" #-i.bak
        fi
done < "$ORIGIN_FILE"

使用示例:

$ cat 1.csv
46700468915;2000
46700568916;3000
46700668917;4000

$ cat 2.csv
4670046;Tele2
4670047;Tele3
4670048;Tele4

$ ./script.sh
46700468915;2000;Tele2
46700568916;3000
46700668917;4000
-----
46700468915;Tele2
46700568916;3000
46700668917;4000

相关内容