Rangement avec décompte d'items avec shell

Résolu
GHISLINO Messages postés 214 Date d'inscription   Statut Membre Dernière intervention   -  
GHISLINO Messages postés 214 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,

J'ai un fichier avec plusieurs Items Fichier1 j'aimerais les ranger en faisant le décompte par items et obtenir le Fichier2

Fichier1

SITE-Id,MRBTS-Id,RMOD-1,RMOD-2,RMOD-3,RMOD-4,RMOD-5,RMOD-6,RMOD-7,RMOD-8,RMOD-9,RMOD-10,RMOD-11
2001,MRBTS-22001,FRMB,FRMB,FRMB,,,,,,,,
2077,MRBTS-22077,FHEB,,FHEB,,FRMB,FHEB,FRMB,FRMB,,,
2001,MRBTS-12001,FHDB,FHDB,FRGY,FHDB,FRGY,FRGY,,,,,
2077,MRBTS-12077,FHDB,FHDB,FRGY,FRGY,FHDB,FRGY,,,,,
2110,MRBTS-12110,FRGU,FXDB


Fichier2

SITE-Id,MRBTS-Id,FRMB,FHDB,FRGY,FHEB,FRGU,FXDB
2001,MRBTS-22001;MRBTS-12001,3,3,3,0
2077,MRBTS-12077;MRBTS-12077,3,3,3,3
2110,MRBTS-12110,0,0,0,0,0,1,1


Merci d'avance

Configuration: Windows / Chrome 80.0.3987.106

5 réponses

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Bonjour,

    Le mieux est d'utiliser un langage un peu plus évolué que shell, genre python. Utilise le module csv pour lire ton fichier, et pour chaque ligne lue, peuple un dictionnaire dont la clé correspond à la première colonne du fichier d'entrée, et dont la valeur est un objet qui corresponds aux compteur et à la liste de MRBTS associés.

    Bonne chance
    0
  2. GHISLINO Messages postés 214 Date d'inscription   Statut Membre Dernière intervention  
     
    bjr mamiemando

    Merci pour ton feedback , malheureusement je ne m'y connais pas en langage Python
    0
  3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    C'est un langage simple, très utilisé, et qui va continuer à être très utilisé donc ça vaut peut être le coup de t'y mettre... Avec un stackoverflow sous la main pour chercher les réponses à tes questions et/ou un tutoriel tu devrais vite apprendre.
    0
  4. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Voici un programme fonctionnel qui répond à ton besoin :

    #!/usr/bin/env python3
    
    import sys
    from collections import defaultdict
    from pprint import pprint
    
    s = """
    SITE-Id,MRBTS-Id,RMOD-1,RMOD-2,RMOD-3,RMOD-4,RMOD-5,RMOD-6,RMOD-7,RMOD-8,RMOD-9,RMOD-10,RMOD-11
    2001,MRBTS-22001,FRMB,FRMB,FRMB,,,,,,,,
    2077,MRBTS-22077,FHEB,,FHEB,,FRMB,FHEB,FRMB,FRMB,,,
    2001,MRBTS-12001,FHDB,FHDB,FRGY,FHDB,FRGY,FRGY,,,,,
    2077,MRBTS-12077,FHDB,FHDB,FRGY,FRGY,FHDB,FRGY,,,,,
    2110,MRBTS-12110,FRGU,FXDB
    """
    
    def parse_csv(s :str) -> dict:
        """
        Parse the input CSV string
        Args:
            s: The string containing the CSV.
        Returns:
            A dict which maps for each site id a dict mapping
            each remaining column name with its correpsonding value.
        """
        # Column names
        keys = None
    
        # Output structure
        map_site = defaultdict(list)
    
        # Read line by line
        for (i, line) in enumerate(s.splitlines()):
            # Skip the line if empty
            if not line:
                continue
            if not keys:
                # Initialize columns names
                keys = line.split(",")
            else:
                # Parse the current row
                row = line.split(",")
                site_id = row[0]
                site = {
                    keys[j] : cell if cell else None
                    for (j, cell) in enumerate(row)
                }
                map_site[site_id].append(site)
        return map_site
    
    # Compute stats
    def compute_stats(map_site :dict) -> tuple:
        """
        Compute stats per site.
        Args:
            map_site: A dict which maps for each site id a dict mapping
            each remaining column name with its correpsonding value.
        Returns:
            A dict which maps each site with its corresponding stats.
        """
        map_stats = dict()
        out_keys = set()
        for (site_id, sites) in map_site.items():
            if site_id not in map_stats.keys():
                map_stats[site_id] = defaultdict(int)
            mrbts_ids = set()
            for site in sites:
                for (key, value) in site.items():
                    if key == "MRBTS-Id":
                        mrbts_ids.add(value)
                    elif key != "SITE-Id" and value is not None:
                        map_stats[site_id][value] += 1
                        out_keys.add(value)
            map_stats[site_id]["MRBTS-Id"] =  mrbts_ids
            map_stats[site_id]["SITE-Id"] = site_id
        return (map_stats, out_keys)
    
    # Export to csv
    def export_csv(map_stats :dict, out_keys :set, f_out):
        """
        Write the output CSV.
        Args:
            map_stats: The map to export.
            out_keys: The column names.
            f_out: The output file descriptor.
        """
        out_keys = ["SITE-Id", "MRBTS-Id"] + sorted(out_keys)
        site_ids = sorted(map_stats.keys())
        s_out = ""
        rows = list()
        rows.append(out_keys)
        for site_id in site_ids:
            row = list()
            for key in out_keys:
                if key == "MRBTS-Id":
                    row.append(";".join(map_stats[site_id][key]))
                else:
                    row.append(str(map_stats[site_id][key]))
            rows.append(row)
        print(
            "\n".join([
                ",".join(row) for row in rows
            ]),
            file = f_out
        )
    
    map_site = parse_csv(s)
    #pprint(map_site)
    (map_stats, out_keys) = compute_stats(map_site)
    #pprint(map_stats)
    export_csv(map_stats, out_keys, sys.stdout)
    

    Ce qui donne :
    SITE-Id,MRBTS-Id,FHDB,FHEB,FRGU,FRGY,FRMB,FXDB
    2001,MRBTS-12001;MRBTS-22001,3,0,0,3,3,0
    2077,MRBTS-12077;MRBTS-22077,3,3,0,3,3,0
    2110,MRBTS-12110,0,0,1,0,0,1

    Si tu décommentes les pprint en fin de programme, tu verras comment sont contruites les différentes maps :

    map_site
    defaultdict(<class 'list'>,
                {'2001': [{'MRBTS-Id': 'MRBTS-22001',
                           'RMOD-1': 'FRMB',
                           'RMOD-10': None,
                           'RMOD-11': None,
                           'RMOD-2': 'FRMB',
                           'RMOD-3': 'FRMB',
                           'RMOD-4': None,
                           'RMOD-5': None,
                           'RMOD-6': None,
                           'RMOD-7': None,
                           'RMOD-8': None,
                           'RMOD-9': None,
                           'SITE-Id': '2001'},
                          {'MRBTS-Id': 'MRBTS-12001',
                           'RMOD-1': 'FHDB',
                           'RMOD-10': None,
                           'RMOD-11': None,
                           'RMOD-2': 'FHDB',
                           'RMOD-3': 'FRGY',
                           'RMOD-4': 'FHDB',
                           'RMOD-5': 'FRGY',
                           'RMOD-6': 'FRGY',
                           'RMOD-7': None,
                           'RMOD-8': None,
                           'RMOD-9': None,
                           'SITE-Id': '2001'}],
                 '2077': [{'MRBTS-Id': 'MRBTS-22077',
                           'RMOD-1': 'FHEB',
                           'RMOD-10': None,
                           'RMOD-11': None,
                           'RMOD-2': None,
                           'RMOD-3': 'FHEB',
                           'RMOD-4': None,
                           'RMOD-5': 'FRMB',
                           'RMOD-6': 'FHEB',
                           'RMOD-7': 'FRMB',
                           'RMOD-8': 'FRMB',
                           'RMOD-9': None,
                           'SITE-Id': '2077'},
                          {'MRBTS-Id': 'MRBTS-12077',
                           'RMOD-1': 'FHDB',
                           'RMOD-10': None,
                           'RMOD-11': None,
                           'RMOD-2': 'FHDB',
                           'RMOD-3': 'FRGY',
                           'RMOD-4': 'FRGY',
                           'RMOD-5': 'FHDB',
                           'RMOD-6': 'FRGY',
                           'RMOD-7': None,
                           'RMOD-8': None,
                           'RMOD-9': None,
                           'SITE-Id': '2077'}],
                 '2110': [{'MRBTS-Id': 'MRBTS-12110',
                           'RMOD-1': 'FRGU',
                           'RMOD-2': 'FXDB',
                           'SITE-Id': '2110'}]})


    map_stats
    {'2001': defaultdict(<class 'int'>,
                         {'FHDB': 3,
                          'FRGY': 3,
                          'FRMB': 3,
                          'MRBTS-Id': {'MRBTS-12001', 'MRBTS-22001'},
                          'SITE-Id': '2001'}),
     '2077': defaultdict(<class 'int'>,
                         {'FHDB': 3,
                          'FHEB': 3,
                          'FRGY': 3,
                          'FRMB': 3,
                          'MRBTS-Id': {'MRBTS-12077', 'MRBTS-22077'},
                          'SITE-Id': '2077'}),
     '2110': defaultdict(<class 'int'>,
                         {'FRGU': 1,
                          'FXDB': 1,
                          'MRBTS-Id': {'MRBTS-12110'},
                          'SITE-Id': '2110'})}


    Bonne chance
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. GHISLINO Messages postés 214 Date d'inscription   Statut Membre Dernière intervention  
     
    Bonsoir mamiemando,

    Merci pour ton coup de main , c est super je vais regarder ça de près.
    0