Jointure externe gauche sur deux fichiers dans unix

j'ai besoin de joindre deux fichiers sur deux champs. Cependant je devrais récupérer toutes les valeurs dans le fichier 1 même si la jointure échoue son comme une jointure externe gauche.

Fichier 1:

01|a|jack|d
02|b|ron|c
03|d|tom|e

Fichier 2:

01|a|nemesis|f
02|b|brave|d
04|d|gorr|h

sortie:

01|a|jack|d|nemesis|f
02|b|ron|c|brave|d
03|d|tom|e||
21
demandé sur fedorqui 2012-11-14 20:09:22

2 réponses

join -t '|' file1 file2 -a1

Options utilisées:

t: Délimiteur.

: détermine le numéro de fichier à partir duquel les lignes non appariées doivent être imprimées.

join -t '|' file1 file2 -a2 faire jointure externe droite.

Echantillonnage

   [aman@aman test]$ cat f1  
    01|a|jack|d

    02|b|ron|c

    03|d|tom|e
    [aman@aman test]$ cat f2
    01|a|nemesis|f

    02|b|brave|d

    04|d|gorr|h
    [aman@aman test]$ join -t '|'  f1 f2 -a1
    01|a|jack|d|a|nemesis|f

    02|b|ron|c|b|brave|d

    03|d|tom|e
24
répondu axiom 2018-01-11 19:23:22

Pour faire exactement ce que la question demande est un peu plus compliquée que la précédente réponse et aurait besoin de quelque chose comme ceci:

sed 's/|/:/2' file1 | sort -t: >file1.tmp
sed 's/|/:/2' file2 | sort -t: >file2.tmp
join -t':' file1.tmp file2.tmp -a1 -e'|' -o'0,1.2,2.2' | tr ':' '|'

Unix rejoindre ne peut les rejoindre sur un champ unique autant que je sache, donc vous devez utiliser des fichiers qui utilisent un délimiteur "joindre deux fichiers sur deux champs", dans ce cas, les deux premiers champs. Je vais utiliser un colon : toutefois si : existe dans n'importe quelle entrée dont vous avez besoin pour utiliser quelque chose d'autre, un onglet caractère par exemple pourrait être un meilleur choix pour l'utilisation de la production. Je re-trie aussi la sortie sur le nouveau champ compound,sort -t:, qui pour l'exemple des fichiers d'entrée ne fait aucune différence, mais serait pour les données du monde réel. sed 's/|/:/2' remplace la deuxième occurrence de pipe avec deux points sur chaque ligne dans le dossier.

fichier1.tmp

01|a:jack|d
02|b:ron|c
03|d:tom|e

fichier2.tmp

01|a:nemesis|f
02|b:brave|d
04|d:gorr|h

Maintenant, nous utilisons join sortie filtrée par tr avec un peu plus avancé options:

  • -t':' spécifiez le délimiteur provisoire de deux points
  • -a1 jointure externe gauche
  • -e'|' spécifie la chaîne de remplacement pour les jointures ratées, essentiellement le délimiteur de sortie final N-1 fois où N est le nombre de champs délimités par pipe joints à la droite du colon Dans le file2.tmp. Dans ce cas N=2 donc un caractère de pipe.
  • -o'0,1.2,2.2' spécifie le format de sortie:
    • 0 rejoindre champ
    • 1.2 Zone 2 du fichier 1.tmp, c'est à dire tout droit de colon
    • 2.2 Zone 2 de file2.tmp
  • tr ':' '|' finalement nous traduisons les colons en pipes pour la sortie finale.

La sortie correspond à présent à la question de l'échantillon de sortie exactement qui la réponse précédente ne pas faire:

01|a|jack|d|nemesis|f
02|b|ron|c|brave|d
03|d|tom|e||
6
répondu idm 2016-10-14 19:52:47