Python 查找每个clientId的新旧映射之间的差异

Python 查找每个clientId的新旧映射之间的差异,python,linux,bash,shell,sed,Python,Linux,Bash,Shell,Sed,我的映射文件如下所示: new\u primary\u mapping.txt {1=[343, 0, 686, 1372, 882, 196], 2=[687, 1, 1373, 883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737, 198, 1570]} {1=[1152, 816, 1488, 336, 1008], 2=[1153, 0, 817, 337, 1489, 1009, 1297], 3=[1, 1154, 1490, 338]

我的映射文件如下所示:

new\u primary\u mapping.txt

{1=[343, 0, 686, 1372, 882, 196], 2=[687, 1, 1373, 883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737, 198, 1570]}
{1=[1152, 816, 1488, 336, 1008], 2=[1153, 0, 817, 337, 1489, 1009, 1297], 3=[1, 1154, 1490, 338]}
{1=[686, 1372, 882, 196], 2=[883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737]}
{1=[1488, 336, 1008], 2=[817, 337, 1489, 1009, 1297], 3=[1490, 338]}
new_secondary_mapping.txt

{1=[343, 0, 686, 1372, 882, 196], 2=[687, 1, 1373, 883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737, 198, 1570]}
{1=[1152, 816, 1488, 336, 1008], 2=[1153, 0, 817, 337, 1489, 1009, 1297], 3=[1, 1154, 1490, 338]}
{1=[686, 1372, 882, 196], 2=[883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737]}
{1=[1488, 336, 1008], 2=[817, 337, 1489, 1009, 1297], 3=[1490, 338]}
在上述映射文件中,每个
clientId
都有新的主映射和新的次映射。例如:
clientId 1
具有
343,06861372882196
新的主映射和
115281614883361008
新的辅助映射。同样,对于其他
客户ID
。下面是我的脚本,它为每个
clientId
打印数组:

#!/bin/bash
mapfiles=(new_primary_mapping.txt new_secondary_mapping.txt)

declare -a arr

mappingsByClientID () {
  id=$1 # 1 to 5 
  file=${mapfiles[$2]} # 0 to 1
  arr=($(sed -r "s/.*\b${id}=\[([^]\]+).*/\1/; s/,/ /g" $file))
  echo "${arr[@]}"
}

# assign output of function to an array
# and get mapping for clientId 3
pri=($(mappingsByClientID 3 0))
snd=($(mappingsByClientID 3 1))

# print whole array
echo "whole arr pri: ${pri[@]}"
echo "whole arr snd: ${snd[@]}"
现在,我有两个其他文件,如下图所示,它们具有相同
clientId
的旧映射

old_primary_mapping.txt

{1=[343, 0, 686, 1372, 882, 196], 2=[687, 1, 1373, 883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737, 198, 1570]}
{1=[1152, 816, 1488, 336, 1008], 2=[1153, 0, 817, 337, 1489, 1009, 1297], 3=[1, 1154, 1490, 338]}
{1=[686, 1372, 882, 196], 2=[883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737]}
{1=[1488, 336, 1008], 2=[817, 337, 1489, 1009, 1297], 3=[1490, 338]}
old_secondary_mapping.txt

{1=[343, 0, 686, 1372, 882, 196], 2=[687, 1, 1373, 883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737, 198, 1570]}
{1=[1152, 816, 1488, 336, 1008], 2=[1153, 0, 817, 337, 1489, 1009, 1297], 3=[1, 1154, 1490, 338]}
{1=[686, 1372, 882, 196], 2=[883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737]}
{1=[1488, 336, 1008], 2=[817, 337, 1489, 1009, 1297], 3=[1490, 338]}
问题陈述

{1=[343, 0, 686, 1372, 882, 196], 2=[687, 1, 1373, 883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737, 198, 1570]}
{1=[1152, 816, 1488, 336, 1008], 2=[1153, 0, 817, 337, 1489, 1009, 1297], 3=[1, 1154, 1490, 338]}
{1=[686, 1372, 882, 196], 2=[883, 197, 736, 1030, 1569], 3=[1374, 2, 884, 737]}
{1=[1488, 336, 1008], 2=[817, 337, 1489, 1009, 1297], 3=[1490, 338]}
现在我需要读取所有四个文件,对于每个
clientId
,我需要找出新映射和旧映射之间的不常见之处(意思不同)

例如:
clientId 1
具有
343,06861372882196
新的主映射和
115281614883361008
新的辅助映射。 而且
clientId 1
具有
686137282196
旧的主要映射和
14883361008
旧的次要映射

因此,我将创建一个pri数组,其中包含以下条目:
3430
,而sec数组中包含以下条目:
1152816
。因为这是每个clientId的新旧映射之间的区别。如何在shell脚本中实现这一点?这可能吗

另外,如果没有区别,那么只需创建一个空数组并记录一条消息

更新:

对于
clientId 1
,它应该打印:

pri=(343 0)
snd=(1152 816)
对于
客户端ID 2

pri=(687 1 1373)
snd=(1153 0)
对于
客户端ID 3

pri=(198 1570)
snd=(1 1154)
注意:只要数字相同,就表示匹配。数字的顺序并不重要。因此,我需要找到那些对每个客户都不常见的数字

这是我删除文件的方式,但当我运行它时,它会给我错误:

for dir_name, numbers in (('primary', pri), ('secondary', snd)):
    for number in numbers:
        for filename in glob.glob('/{}/proc_{}_for_*.log'.format(dir_name, number)):
             os.unlink(filename)
以下是我得到的错误:

NameError: name 'pri' is not defined
标准命令 使用标准unix命令sort和comm的简短解决方案

new_primary=(343 0 686 1372 882 196)
old_primary=(686 1372 882 196)
comm -23 <( printf "%s\n" "${new_primary[@]}" | sort ) <( printf "%s\n" "${old_primary[@]}" | sort )

Python
解决方案:

diff_mappings.py
脚本:

import sys, re, json

with open(sys.argv[1]) as old_primary, open(sys.argv[2]) as new_primary, \
    open(sys.argv[3]) as old_second, open(sys.argv[4]) as new_second:

    prepare_json = lambda f: json.loads(re.sub(r'([0-9]+)=', '"\\1":', f.read())) 
    old_pr_data = prepare_json(old_primary)
    new_pr_data = prepare_json(new_primary)
    old_snd_data = prepare_json(old_second)
    new_snd_data = prepare_json(new_second)

    for k in sorted(old_pr_data):
        print('ClientId ' + k)
        print('pri=({})'.format(' '.join(map(str, set(old_pr_data[k]) ^ set(new_pr_data[k])))))
        print('snd=({})\n'.format(' '.join(map(str, set(old_snd_data[k]) ^ set(new_snd_data[k])))))
用法(输入文件的顺序很重要,但也可以重新安排方法,直接在脚本中按名称访问文件):

输出:

ClientId 1
pri=(0 343)
snd=(1152 816)

ClientId 2
pri=(1 687 1373)
snd=(0 1153)

ClientId 3
pri=(198 1570)
snd=(1 1154)

问题:1)你能认为数组总是在增长吗?这意味着新阵列中的信息将比旧阵列中的信息更多?2) 数组是否总是按新旧顺序生成?对于每个clientId,新数组的大小将始终小于旧数组。在这个例子中,我有相反的答案。我只是想在这个例子中说清楚,所以我想到了这个。没有回答你的第二个问题吗?例如
old\u primary
1=[686137282196]
new\u primary
1=[3431968821372686]
@Allan它可以是任何顺序。我想一定有办法找到两个数组之间的差异?@RomanPerekhrest为什么你不认为这是一种差异<代码>新建小学
1=[343,06861372882196]
旧小学
1=[686137282196]
。这里的差异仅为343 0适合小学,因为其他数字是匹配的?谢谢你的建议。我如何将它与我的脚本集成,以及如何处理旧的和新的二级映射?啊,这非常紧凑。美好的还有什么方法可以让它只为传递到此脚本的
clientId
打印
pri
snd
数组,而不是打印所有内容?假设我通过了
clientId
3,那么它应该只为该clientId打印
pri
snd
数组?或者,我可以使用一个额外的参数,检查循环中的k并相应地打印。当然,如果事先知道键值,您可以直接访问所需的键,例如
k='3';打印('ClientId'+k);print('pri=({})').format('''.join(映射,集(旧数据[k])^set(新数据[k]))
aah我明白了。。有道理。。让我测试一下,看看它是什么样子。。我刚才在读它,我也可以用python删除文件,所以我会修改这个脚本,使它也能工作。我还在想,我们能把pri和snd作为一个合适的数组吗?因为我需要迭代它们来删除文件。我已经更新了我的问题,在其中我添加了我是如何做的,但由于某些原因,当前的实现无法工作。