J'ai deux fichiers à partir desquels 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
La commande join
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
Vous devez juste ajouter les zéros aux lignes sans correspondance. Vous pouvez utiliser le commutateur -e
pour cela:
join -12 -a2 file1 file2 -o2.1,2.2,1.1 -e0
Utiliser 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 à l'aide du champ 1 (-1 1
) du fichier2 et du 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 manque un champ, mettez 0 (-e0
)
Si l'un des deux fichiers contient plusieurs enregistrements, ajoutez-les (dans ce cas, fichier2) (-a1
)
Veuillez vous référer à la page de manuel de la commande join
Un peu awk
magic:
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
sortie
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}
Fonctionne sur file1
(FNR==NR
) et crée une structure clé-valeur. La clé est la deuxième colonne ($2
) de file1
, la valeur est la première colonne ($1
) de file1
{if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}
Fonctionne sur file2
et
if(a[$1]==""){a[$1]=0}
Si la clé dans la première colonne ($1
) dans file2
n'existe pas dans file1
, nous avons besoin d'un 0
print $1,$2,a[$1]
Imprimer (en utilisant print
name__) les première et deuxième colonnes de file2
et la valeur de la structure clé-valeur avec la clé de la première colonne ($1
) de file2
ou
printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'
Imprimez (à l'aide de printf
name__) les première et deuxième colonnes de file2
et 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
- String
\n
- Newline
Utiliser 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 être parfois plus lisible de cette façon.