2012-05-22 58 views
0

我已经尝试了所有在线搜索的选项来解决我的问题,但没有好的结果。在bash(Linux)中查找另一个csv中的值(如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 | CORK | APTS | CORKKIN |

123 | 21 | 0452 | IE | IE | 1 | CORKCOR | NAME | HARRINGTON | DUBLIN | 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的值。

实施例: 文件1,行1,POS 7:file2中MAYOBAN 找到MAYOBAN,返回POS 3(2400)

输出应该是这样的:

等...

请帮 亚切克

+0

拆分成数组并检查可能是重复的。不知道这是做到这一点的方式,但这是我的第一个想法。 – keyser

回答

5

一点的办法,远处是完美的:

DELIMITER="|" 

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

[Wikipedia](http://en.wikipedia.org/wiki/Comma-separated_values):“每条记录由字段组成,由其他字符或字符串分隔,最常见的是文字或逗号。”和“在通常的用法中,几乎任何分隔符分隔的文本数据可能被称为'CSV'文件。” –

+0

@丹尼斯威廉姆森:谢谢,给我启发。 – sgibb

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并创建数组条目f或字段7的每个值。只需引用数组元素即可创建它(具有空值)。 FNR是当前文件中的记录编号,NR是所有文件中的记录编号。当它们相等时,第一个文件正在处理中。指令next读取下一条记录,创建一个循环。当FNR == NR不再为真时,将处理后续文件。

因此,file2.csv现在处理,如果它有一个字段1存在于数组中,则它的字段3被打印。

+0

太棒了!这工作像一个魅力。其实冷杉选项是好的,因为我不需要排序。输出用于统计目的,所以如果数量正常,没关系。我尝试过AWK,但没有很好的结果。 – Yasapl

+0

@Yasapl:我在我的答案中添加了一个AWK版本。如果您发现我的答案有用,请将其标记为已接受,并将其上传。谢谢。 –

0
cut -d\| -f7 file1.csv|while read line 
do 
    grep $line file1.csv|cut -d\| -f3 
done 
相关问题