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
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.
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
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)
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
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