web-dev-qa-db-fra.com

comment fusionner deux fichiers de manière cohérente ligne par ligne

J'ai deux fichiers ( fichier1.txt & fichier2.txt ), les fichiers ne sont que des exemples.

Comment fusionner les deux fichiers, afin de créer le fichier - merge_files.txt as example 3

J'écris maintenant le script ksh, la fusion peut donc être réalisée avec ksh, awk, sed, Perl one liner, etc.

Contexte - Pourquoi dois-je fusionner les fichiers: Mon objectif est de renommer le fichier OLD (existe dans le premier champ) en NOUVEAU fichier (existe dans le deuxième champ), 

exemple 1

more file1.txt

/etc/port1-192.9.200.1-255.555.255.0
/etc/port2-192.9.200.1-255.555.255.0
/etc/port3-192.9.200.1-255.555.255.0
/etc/port4-192.9.200.1-255.555.255.0
/etc/port5-192.9.200.1-255.555.255.0
.
.
.
.

exemple2

more file2.txt

/etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.90.2.1-255.555.0.0
.
.
.
.

exemple3

 more merge_files.txt



 /etc/port1-192.9.200.1-255.555.255.0  /etc/port1-192.90.2.1-255.555.0.0
 /etc/port2-192.9.200.1-255.555.255.0  /etc/port2-192.90.2.1-255.555.0.0
 /etc/port3-192.9.200.1-255.555.255.0  /etc/port3-192.90.2.1-255.555.0.0
 /etc/port4-192.9.200.1-255.555.255.0  /etc/port4-192.90.2.1-255.555.0.0
 /etc/port5-192.9.200.1-255.555.255.0  /etc/port5-192.90.2.1-255.555.0.0
 .
 .
 .
 .
 .

example4 (structure merge_files.txt)

 first field                           second field

 OLD file                              NEW file
57
user1121951

Vous pouvez utiliser paste pour formater les fichiers côte à côte:

$ paste -d" " file1.txt file2.txt
/etc/port1-192.9.200.1-255.555.255.0 /etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.9.200.1-255.555.255.0 /etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.9.200.1-255.555.255.0 /etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.9.200.1-255.555.255.0 /etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.9.200.1-255.555.255.0 /etc/port5-192.90.2.1-255.555.0.0

Par exemple.:

$ paste -d" " file1.txt file2.txt | while read from to; do echo mv "${from}" "${to}"; done
mv /etc/port1-192.9.200.1-255.555.255.0 /etc/port1-192.90.2.1-255.555.0.0
mv /etc/port2-192.9.200.1-255.555.255.0 /etc/port2-192.90.2.1-255.555.0.0
mv /etc/port3-192.9.200.1-255.555.255.0 /etc/port3-192.90.2.1-255.555.0.0
mv /etc/port4-192.9.200.1-255.555.255.0 /etc/port4-192.90.2.1-255.555.0.0
mv /etc/port5-192.9.200.1-255.555.255.0 /etc/port5-192.90.2.1-255.555.0.0

Bien sûr, vous voudriez lancer quelques vérifications de sécurité ([ -f "${from}" ], ...).

Disclaimer: Ne fonctionne que s'il n'y a pas d'espace dans vos noms de fichiers.

105

Ce Perl one-liner affichera les changements de noms nécessaires

Perl -e 'open $f[$_-1], "file$_.txt" for 1,2; print "rename @n\n" while chomp(@n = map ''.<$_>, @f)'

Si cela fonctionne pour vous, remplacez la déclaration print par un vrai nom et utilisez

Perl -e 'open $f[$_-1], "file$_.txt" for 1,2; rename @n while chomp(@n = map ''.<$_>, @f)'

pour renommer

4
Borodin
paste -d " " file1.txt file2.txt

Fonctionne très bien pour ce travail . Mais si vous manipulez des fichiers texte dans un environnement Windows et utilisez le GNU coller, assurez-vous de transformer les fichiers au format Unix (CR) et de ne pas les utiliser avec ( CR-LF).

Le collage GNU ne semble pas gérer correctement les formats DOS et l'analyse est imprévisible, la sortie attendue est irrégulière et inattendue, sans avertissements.

Vous pouvez utiliser GVIM pour les transformer facilement (Édition/Paramètres de fichier/Format de fichier)

1
migs

Moyens complètement indépendants pour atteindre l'objectif du PO de renommer les fichiers numérotés:

for f in {1..5}; do mv /etc/port$d-192.9.200.1-255.555.255.0 /etc/port$d-192.90.2.1-255.555.0.0; done

Une autre possibilité basée sur rename

rename 's/192.9.200.1/192.90.2.1/' /etc/port[1-5]-192.9.200.1-255.555.255.0
0
Vincent Fourmond

commander

paste file1 file2

sortie

/etc/port1-192.9.200.1-255.555.255.0    /etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.9.200.1-255.555.255.0    /etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.9.200.1-255.555.255.0    /etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.9.200.1-255.555.255.0    /etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.9.200.1-255.555.255.0    /etc/port5-192.90.2.1-255.555.0.0
0
user8854776