2012-07-23 51 views
1

所以我有“钥匙”的文件,例如:使用键搜索/替换:bash中的文件中的值?

key1 
key2 
key3 

和我有密钥的文件:值对:

key1:value1 
key2:value2 
key3:value3 

我想取代我的文件中的密钥键和它们在键值文件中的对应值。因此,密钥文件将看起来像这样完成后:

value1 
value2 
value3 
... 

什么是在bash中做到这一点的最佳方法?请注意,密钥可能会在密钥文件中出现多次,但应该只在键值文件中出现一次。

回答

3

如果连接命令在环境中是可用的,下面应该工作。需要通过awk命令添加索引以恢复原始键顺序(通过Schwartzian变换)。

join -o 1.1,2.2 -t':' -1 2 -2 1 <(awk '{print(NR":"$0)}' key_file | sort -k2,2 -t':') <(sort -k1,1 -t':' key_values_file) | sort -k1,1 -t':' | cut -f2 -d':' 
+0

不确定这是否按我指定的方式工作。我的密钥文件有67,683个条目。由此产生的文件有37,098个条目。我提到一个密钥可能会在密钥文件中出现多次(并且我希望相应的值在输出中正好显示该次数)。 – Rsaesha 2012-07-23 18:14:02

+0

我的不好。我有一些文件困惑。 :D谢谢,你的回答很好! – Rsaesha 2012-07-23 18:20:25

0

我知道你想要“bash”,但这很简单,用一个快速的perl脚本解决。假设你有文件pairs.txtkeys.txt

use strict; 
my %keys2values; 

# read through the pairs file to get the key:value mapping 
open PAIRS, "cat pairs.txt |" ; 
while(<PAIRS>) { 
    chomp $_; 
    my ($key,$value) = split(":",$_); 
    $keys2values{$key} = $value; 
} 

open KEYS, "cat keys.txt |"; 
while(<KEYS>) { 
    chomp $_; 
    my $key = $_; 
    if(defined $keys2values{$key}) { 
     print "$keys2values{$key}\n"; 
    } 
    # if a key:value pair isn't defined, just print the key 
    else { 
     print "$key\n"; 
    } 
} 
0

由于我有一个纯粹的bash解决方案,我只是发布这个解决方案。它只能在bash 4+中工作,因为它使用关联数组。

#!/bin/bash 

while IFS=: read key value; do 
    declare -A hash[$key]=$value 
done < pairfile 

while read key; do 
    printf '%s\n' "${hash[$key]}" 
done < keyfile 
+1

我冒昧地在第一个循环中修复了一些错误,因为我正准备发布相同的解决方案。 – chepner 2012-07-23 17:54:03