Python 使用两个文件进行文本处理

Python 使用两个文件进行文本处理,python,text,awk,Python,Text,Awk,我有两个以下格式的文本文件: 第一个是每一行: Key1:Value1 第二点是: Key2:Value2 有没有办法将file1中的Value1替换为Value2中的Value2作为file2中的键 例如: file1 = {} for line in open('file1', 'r'): k, v = line.strip().split(':') file1[k] = v 文件1: foo:hello bar:world 文件2: hello:adam bar:eve

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

第一个是每一行:

Key1:Value1

第二点是:

Key2:Value2

有没有办法将
file1
中的
Value1
替换为
Value2
中的
Value2
作为
file2
中的键

例如:

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

foo:hello
bar:world
文件2:

hello:adam
bar:eve
我想得到:

foo:adam
bar:eve

并非每行上的两个文件都必须匹配。这可以用awk或其他什么工具整洁地完成吗?或者我应该用Python简单地完成吗?

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

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。例如,如果您的文件1包含
foo:bar
,则您的文件1 dict是
{bar:foo}

for key in set(file1) & set(file2):
    result[file1[key]] = file2[key]
基本上,您可以使用集合交集快速找到公共元素,这样就可以保证这些元素在file2中,并且您不会浪费时间检查它们的存在

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

一旦您拥有:

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'}

如在你的例子中,你使用的是<代码>键> <代码>值<代码> >代码>文件< <代码> >代码>键<代码> >代码2>代码>

如果你不考虑使用基本的UNIX/Linux命令作弊,那么这里有一个使用粘贴和AWK的解决方案。
paste file1.txt file2.txt | awk-F:“{print$1”:“$3}”
join-t:-12-21-o 0 2.2-a 2 awk解决方案:

join -t : -1 2 -2 1 -o 0 2.2 -a 2 <(sort -k 2 -t : file1) <(sort file2)
awk '
  BEGIN {FS = OFS = ":"}
  NR==FNR {val[$1] = $2; next}
  $1 in val {$2 = val[$1]}
  {print}
}' file2 file1
这可能适合您(可能是GNU-sed):

TXR:

运行:


可能,
collections.OrderedDict
(Python 2.7+和3.1+)可以作为一个选项,将值按原始顺序写回文件(如果要写回)。[我不喜欢为字典指定的fileX名称。此外,打开的文件应始终在运行时之前关闭。]此解决方案假设
file1
中的键控数据位于该文件的行号上,与发生引用的
file2
中的行号相同。在给出的小样本数据中,我们有理由假设这只是巧合。
@(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