2012-05-05 36 views
5

我有以下格式两个文本文件中的文本处理:有两个文件

首先是这对每行:

Key1:Value1

二是这样的:

Key2:Value2

有没有一种方法可以代替Value1file1Value2从使用它作为密钥获得file2

例如:

文件1:

foo:hello 
bar:world 

文件2:

hello:adam 
bar:eve 

我想获得:

foo:adam 
bar:eve 

不一定有之间的匹配每个李上的两个文件东北。这可以在awk或其他东西中整齐地完成,还是我应该在Python中天真地做到这一点?

回答

3

创建两个词典,每个文件一个。例如:

file1 = {} 
for line in open('file1', 'r'): 
    k, v = line.strip().split(':') 
    file1[k] = v 

或者如果你喜欢一个班轮:

file1 = dict(l.strip().split(':') for l in open('file1', 'r')) 

然后,你可以这样做:

result = {} 
for key, value in file1.iteritems(): 
    if value in file2: 
     result[key] = file2[value] 

另一种方法是你可以生成键值反向配对file1并使用set。例如,如果你的file1包含foo:bar,你的file1字典是{bar: foo}

for key in set(file1) & set(file2): 
    result[file1[key]] = file2[key] 

基本上,你可以快速找到使用交集共同的元素,因此这些元素保证在文件2,你不要浪费时间检查它们的存在。

编辑:正如@pepr指出如果订单对您很重要,您可以使用collections.OrderedDict作为第一种方法。

+2

可能'collections.OrderedDict'(Python 2.7+和3.1+)可能是一个选项,以原始顺序将值写回文件(如果要写回)。 [我不喜欢给字典的** fileX **名字。此外,打开的文件应该比运行时更早关闭。] – pepr

+0

好点,我没有想过这个命令。 – spinlok

0

一旦你有:

file1 = {'foo':'hello', 'bar':'world'} 
file2 = {'hello':'adam', 'bar':'eve'} 

你可以做一个丑陋的一个班轮:

print dict([(i,file2[i]) if i in file2 else (i,file2[j]) if j in file2 else (i,j) for i,j in file1.items()]) 
{'foo': 'adam', 'bar': 'eve'} 

如在你的榜样,你在file2同时使用的file1keysvalueskeys

0

如果你不考虑使用基本的Unix/Linux命令作弊,那么这里是一个使用paste和awk的解决方案。

paste file1.txt file2.txt | awk -F ":" '{ print $1":"$3 }'

+0

该解决方案假定'file1'中的键控数据在文件的同一行号上找到,该文件与引用发生处'file2'中的行号一致。假设在给定的小样本数据中,这恰好是巧合的,这是合理的。 – Kaz

1
join -t : -1 2 -2 1 -o 0 2.2 -a 2 <(sort -k 2 -t : file1) <(sort file2) 

输入文件必须在他们加入了对字段排序。

选项:

  • -t : - 使用冒号作为分隔符
  • -1 2 - 加入对文件1
  • -2 1场2 - 加入的文件2
  • -o 0 2.2场1 - 从file2输出连接字段后跟字段2(用分隔符分隔)
  • -a 2 - 输出未连接的行从文件2
2

awk的解决方案:

awk ' 
    BEGIN {FS = OFS = ":"} 
    NR==FNR {val[$1] = $2; next} 
    $1 in val {$2 = val[$1]} 
    {print} 
}' file2 file1 
0

这可能会为你(可能是GNU SED)工作:

sed 's#\([^:]*\):\(.*\)#/\\(^\1:\\|:\1$\\)/s/:.*/:\2/#' file2 | sed -f - file1 
0

TXR:

@(next "file2") 
@(collect) 
@key:@value1 
@ (cases) 
@ (next "file1") 
@ (skip) 
@value2:@key 
@ (or) 
@ (bind value2 key) 
@ (end) 
@ (output) 
@value2:@value1 
@ (end) 
@(end) 

运行:

$ txr subst.txr 
foo:adam 
bar:eve