Fusionner des fichiers à l'aide d'une colonne commune


8

J'ai deux fichiers dont je veux créer un troisième qui contient toutes les informations.

fichier 1:

a 111 
b 222 
c 333 
d 666 
e 777 

fichier 2:

111 x1  
222 x2
333 x3
444 x4 
555 x5 
666 x6 
777 x7 
888 x8

Je voudrais les combiner comme suit:

111  x1  a
222  x2  b
333  x3  c
444  x4  0
555  x5  0
666  x6  d
777  x7  e
888  x8  0

Remarque:

La deuxième colonne du fichier 1 est un sous-ensemble de la première colonne du fichier 2

Réponses:


7

La joincommande fait presque ce dont vous avez besoin, si les fichiers sont triés comme dans vos exemples:

join -12 -a2 file1 file2 -o2.1,2.2,1.1

Il vous suffit d'ajouter les zéros aux lignes sans correspondance. Vous pouvez utiliser le -ecommutateur pour cela:

join -12 -a2 file1 file2  -o2.1,2.2,1.1 -e0

si vous ajoutez le -e0pas besoin de perl :)
LilloX

@LilloX: C'est vrai, merci. J'ai essayé mais j'ai échoué (faute de frappe).
choroba

13

Utilisation de join:

join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1

La commande join joint les lignes de deux fichiers qui partagent un champ de données commun. Dans ce cas: Joignez le fichier2 et le fichier1 en utilisant le champ 1 ( -1 1) du fichier2 et le champ 2 ( -2 2) du fichier1.

La sortie sera: "champ joint, champ 2 du fichier2, champ 1 du fichier1" ( -o'0,1.2,2.1'), s'il y a un champ manquant, mettre 0 ( -e0)

Si l'un des deux fichiers a plus d'enregistrements, ajoutez-les (dans ce cas, fichier2) ( -a1)

Veuillez vous référer à la page de manuel de la commande join


Bien. Pourriez-vous ajouter un peu d'explication?
Lety

Bien sûr, mis à jour :)
LilloX

5

Un peu de awkmagie:

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; \
    printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}' \
    file1 file2

ou

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0};
    print $1,$2,a[$1]}' file1 file2

Production

111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Explication

  • FNR==NR{a[$2]=$1;next}

    Exécute file1( FNR==NR) et crée une structure de valeur-clé. La clé est la deuxième colonne ( $2) de file1, la valeur est la première colonne ( $1) defile1

  • {if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}

    Renverse file2et

    • if(a[$1]==""){a[$1]=0}

      Si la clé de la première colonne ( $1) dans file2n'existe pas dans file1, nous avons besoin d'un0

    • print $1,$2,a[$1]

      Imprimer (en utilisant print) la première et la deuxième colonne de file2et la valeur de la structure clé-valeur avec la clé de la première colonne ( $1) defile2

      ou

    • printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'

      Imprimer (en utilisant printf) la première et la deuxième colonne de file2et la valeur de la structure clé-valeur avec la clé de la première colonne ( $1) de file2.

      • FS est le séparateur entre les colonnes, extrait du fichier d'entrée

      • "%s%s%s%s%s\n"

        est le formatage de la sortie

        • %s - Chaîne

        • \n - Nouvelle ligne


Pourriez-vous expliquer le code?
gforce89

Bien sûr, la réponse a été mise à jour.
AB

1

Utilisation de q :

$ q "select f2.c1, f2.c2, ifnull(f1.c1,0) from file_2.txt f2 LEFT JOIN file_1.txt f1 on f1.c2 = f2.c1 "
111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Il peut parfois être plus lisible de cette façon.


1
Pour ceux qui se demandent, qest dans le package python3-q-text-as-data(Python 3) et dans le package python-q-text-as-data(Python 2).
kos

Merci, mais où puis-je obtenir ce qpackage? Je ne semble pas pouvoir installer ni l'un python-q-text-as-datani l' autre python3-q-text-as-data. "E: impossible de localiser le paquet python3-q-text-as-data". Mon système a déjà installé python, python2.7, python3et python3.4.
Paddy Landau

Le package est peut-être trop nouveau et n'est pas disponible dans votre version de distribution. Vous pouvez le cloner Github: github.com/harelba/q
Vi.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.