在bash(Linux)中从另一个csv(如vlookup)中查找值

时间:2012-05-22 07:36:38

标签: linux bash csv compare vlookup

我已经尝试过我在网上找到的所有选项来解决我的问题,但没有很好的结果。

基本上我有两个csv文件(管道分隔):

file1.csv:

123 | 21 | 0452 | IE | IE | 1 | MAYOBAN | BRIN | OFFICE | STREET | MAIN STREET | MAYOBAN |

123 | 21 | 0453 | IE | IE | 1 | CORKKIN | ROBERT | SURNAME | |软木APTS | CORKKIN |

123 | 21 | 0452 | IE | IE | 1 | CORKCOR | NAME | HARRINGTON |都柏林| STREET | CORKCOR |

file2.csv:

MAYOBAN | BANGOR | 2400

MAYOBEL | BELLAVARY | 2400

CORKKIN | KINSALE | 2200

CORKCOR |软木| 2200

DUBLD11 |都柏林11 | 2100

我需要一个linux bash脚本,根据file1中pos7的内容从file2中找到pos.3的值。

实施例: file1,line1,pos 7:MAYOBAN 在file2中找到MAYOBAN,返回pos 3(2400)

输出应该是这样的:

2400

2200

2200

等...

请帮忙 亚切克

4 个答案:

答案 0 :(得分:5)

一个小小的方法,远远不够完美:

DELIMITER="|"

for i in $(cut -f 7 -d "${DELIMITER}" file1.csv ); 
do 
    grep "${i}" file2.csv | cut -f 3 -d "${DELIMITER}"; 
done

答案 1 :(得分:2)

这将有效,但由于必须对输入文件进行排序,因此输出顺序将受到影响:

join -t '|' -1 7 -2 1 -o 2.3 <(sort -t '|' -k7,7 file1.csv) <(sort -t '|' -k1,1 file2.csv)

输出如下:

2200
2200
2400

没用。为了获得有用的输出,请包含键值:

join -t '|' -1 7 -2 1 -o 0,2.3 <(sort -t '|' -k7,7 file1.csv) <(sort -t '|' -k1,1 file2.csv)

然后输出如下:

CORKCOR|2200
CORKKIN|2200
MAYOBAN|2400

修改

这是一个AWK版本:

awk -F '|' 'FNR == NR {keys[$7]; next} {if ($1 in keys) print $3}' file1.csv file2.csv

循环遍历file1.csv并为字段7的每个值创建数组条目。只需引用数组元素即可创建它(带有空值)。 FNR是当前文件中的记录号,NR是所有文件中的记录号。当它们相等时,正在处理第一个文件。 next指令读取下一条记录,创建一个循环。当FNR == NR不再为真时,将处理后续文件。

所以现在处理了file2.csv,如果它有一个存在于数组中的字段1,那么它的字段3就会打印出来。

答案 2 :(得分:1)

您可以使用Miller(https://github.com/johnkerl/miller)。

从input01.txt开始

123|21|0452|IE|IE|1|MAYOBAN|BRIN|OFFICE|STREET|MAIN STREET|MAYOBAN|
123|21|0453|IE|IE|1|CORKKIN|ROBERT|SURNAME|CORK|APTS|CORKKIN|
123|21|0452|IE|IE|1|CORKCOR|NAME|HARRINGTON|DUBLIN|STREET|CORKCOR|

和input02.txt

MAYOBAN|BANGOR|2400
MAYOBEL|BELLAVARY|2400
CORKKIN|KINSALE|2200
CORKCOR|CORK|2200
DUBLD11|DUBLIN 11|2100

并运行

mlr --csv -N --ifs "|" join  -j 7 -l 7 -r 1 -f input01.txt then cut -f 3 input02.txt

您将拥有

2400
2200
2200

一些注意事项:

  • -N设置不带标题的输入和输出;
  • --ifs "|"设置输入字段分隔符;
  • -l 7 -r 1设置输入文件的联接字段;
  • cut -f 3从联接输出中提取名为3的字段

答案 3 :(得分:0)

cut -d\| -f7 file1.csv|while read line
do 
  grep $line file1.csv|cut -d\| -f3
done