我有两个 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
这里有几个问题:
您需要适当地设置 awk 的字段分隔符:默认情况下它是空格,而您的文件似乎由分号分隔
你正尝试匹配部分字段:
4670046
在a
但46700468915
不在您似乎对要匹配的字段感到困惑,
$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
作为-a
rray 然后用来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