Fusionner des lignes alternatives à partir de deux fichiers


9

Fichier1:

.tid.setnr := 1123 
.tid.setnr := 3345 
.tid.setnr := 5431
.tid.setnr := 89323

Fichier2:

.tid.info := 12
.tid.info := 3
.tid.info := 44
.tid.info := 60

Fichier de sortie:

.tid.info := 12
.tid.setnr := 1123
.tid.info := 3
.tid.setnr := 3345
.tid.info := 44
.tid.setnr := 5431
.tid.info := 60
.tid.setnr := 89323

2
Veuillez toujours mentionner votre système d'exploitation. Beaucoup d'outils standard se comportent différemment sur les différents systèmes d'exploitation, nous devons donc savoir ce que vous utilisez.
terdon

Réponses:




5

La pastesolution est la plus portable et la plus efficace. Je ne mentionne cette alternative que si vous préférez son comportement dans le cas où les deux fichiers n'ont pas le même nombre de lignes:

Avec GNU sed:

sed Rfile1 file2

Si file1a moins de lignes que file2, alors quand file1est épuisé, sedne produira rien pour lui (par opposition aux lignes vides pour paste).

Si le file1nombre de lignes est supérieur à file2, ces lignes supplémentaires seront supprimées (par opposition à l'impression de lignes vides pour file2avec paste).

$ paste a b
1       a
2       b
3
4
$ paste -d \\n a b
1
a
2
b
3

4

$ sed Rb a
1
a
2
b
3
4
$ sed Ra b
a
1
b
2

4

En utilisant awk( gawk, nawk, mawk):

awk 'NR==FNR {x[FNR]=$0;next} {print x[FNR]"\n"$0}' file2 file1 > outputfile
  • NR==FNR {x[FNR]=$0;next}: NR==FNRest mis en correspondance uniquement si le numéro d'enregistrement en cours est égal au numéro d'enregistrement du fichier en cours (il n'est donc mis en correspondance que lors du traitement du premier fichier): stocke l'enregistrement actuellement traité dans le tableau xà un index égal au numéro d'enregistrement du fichier en cours et ignore la record actuel
  • {print x[FNR]"\n"$0}: imprime le contenu du tableau xà un index égal au numéro d'enregistrement du fichier courant suivi d'une nouvelle ligne et du contenu de l'enregistrement courant
~/tmp$ cat file1
.tid.setnr := 1123
.tid.setnr := 3345
.tid.setnr := 5431
.tid.setnr := 89323
~/tmp$ cat file2
.tid.info := 12
.tid.info := 3
.tid.info := 44
.tid.info := 60
~/tmp$ awk 'NR==FNR {x[FNR]=$0;next} {print x[FNR]"\n"$0}' file2 file1
.tid.info := 12
.tid.setnr := 1123
.tid.info := 3
.tid.setnr := 3345
.tid.info := 44
.tid.setnr := 5431
.tid.info := 60
.tid.setnr := 89323

Cela donne la sortie mais pas exactement la même chose que je voulais. Les lignes tid.info viennent après les lignes tid.setnr dans mon fichier de sortie.
pmaipmui

@Nainita C'est ce que vous montrez dans votre exemple de sortie.
kos

@Nainita Quoi qu'il en soit pour changer l'ordre de la sortie, vous pouvez simplement changer file1et file2dans la commande.
kos

Oui ... J'ai fait la même chose mais il imprimait exactement comme avant. après avoir imprimé tid.setnr, il s'agissait de tid.info.
pmaipmui

1
@mikeserv Cependant, depuis que j'y suis, j'ai mawkégalement essayé , et il fonctionne également. En tout cas je être raisonnable ne vois pas pourquoi il ne devrait pas fonctionner juste l'inverse (c. -à- tout par les fichiers de commutation). Ce n'est pas que l'on se awksoucie de l'entrée, les lignes sont des lignes. Si quelque chose n'était pas supporté par sa version, il se serait cassé la première fois. Bien plus facilement, simplement OP a fait une erreur en changeant les fichiers d'entrée dans les arguments.
kos

-1

La solution la plus simple est donnée ci-dessous.

cat file1 >> file2

ou

cat file2 >> file1

1
sachin, relisez la question; cela ajoute le contenu d'un fichier au contenu d'un autre fichier. Il ne fusionne pas les fichiers en alternant les lignes (donc une ligne de file1puis une ligne de file2et ainsi de suite ...)
don_crissti
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.