使用两个文件处理文本

时间:2012-05-05 08:13:55

标签: python text awk

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

首先是每一行:

Key1:Value1

第二个是:

Key2:Value2

我可以用Value1替换file1Value2取代file2作为foo:hello bar:world 中的关键字吗?

例如:

文件1:

hello:adam
bar:eve

file2的:

foo:adam
bar:eve

我想得到:

{{1}}

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

7 个答案:

答案 0 :(得分: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反向生成键值对并使用集合。例如,如果您的file1包含foo:bar,则您的file1 dict为{bar: foo}

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

基本上,你可以使用set intersection快速找到常用元素,因此这些元素保证在file2中,你不会浪费时间检查它们的存在。

修改:正如@pepr所指出的那样如果订单对您很重要,您可以使用collections.OrderedDict作为第一种方法。

答案 1 :(得分:2)

awk解决方案:

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

答案 2 :(得分: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栏
  • -2 1 - 加入文件2的第1栏
  • -o 0 2.2 - 输出连接字段,然后输出file2中的字段2(用分隔符分隔)
  • -a 2 - 从file2输出未加入的行

答案 3 :(得分: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'}

在您的示例中,您在keys中同时使用values file1 keys作为file2

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

这可能适合你(可能是GNU sed):

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

答案 6 :(得分: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