it-swarm.com.de

zwei Dateien konsistent zeilenweise zusammenführen

Ich habe zwei Dateien ( file1.txt & file2.txt ), Dateien sind nur Beispiele.

So fügen Sie die beiden Dateien zusammen, um die Datei - merge_files.txt zu erstellen (siehe Beispiel 3)

Ich schreibe jetzt ein ksh-Skript, so dass das Zusammenführen mit ksh, awk, sed, einem Perl-Liner usw. erfolgen kann

Hintergrund - Warum muss ich die Dateien zusammenführen? Mein Ziel ist das Umbenennen der OLD-Datei (im ersten Feld vorhanden) in NEW-Datei (im zweiten Feld vorhanden). 

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

beispiel2

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

beispiel3

 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 (Struktur merge_files.txt)

 first field                           second field

 OLD file                              NEW file
57
user1121951

Sie können paste verwenden, um die Dateien nebeneinander zu formatieren:

$ 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

Z.B.:

$ 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

Natürlich möchten Sie einige Sicherheitsprüfungen einreichen ([ -f "${from}" ], ...).

Haftungsausschluss: Funktioniert nur, wenn Ihre Dateinamen keine Leerzeichen enthalten.

105

Dieser Perl-Einzeiler zeigt die erforderlichen Umbenennungen an

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

Wenn dies für Sie funktioniert, ersetzen Sie die print-Anweisung durch eine echte Umbenennung und verwenden Sie sie

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

die eigentliche Umbenennung vornehmen

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

Funktioniert hervorragend für diesen Job. Wenn Sie jedoch Textdateien in einer Windows-Umgebung verarbeiten und GNU einfügen, stellen Sie sicher, dass die Dateien in das Unix-Format (CR) umgewandelt werden und keine Dateien mit ( CR-LF).

GNU-Paste scheint DOS-Formate nicht richtig zu verarbeiten, und das Parsen ist unvorhersehbar. Die erwartete Ausgabe ist unberechenbar und ohne Warnungen unerwartet.

Sie können GVIM verwenden, um sie leicht umzuwandeln (Bearbeiten/Dateieinstellungen/Dateiformat).

1
migs

Vollständig voneinander unabhängige Möglichkeiten, um das Ziel des OP zu erreichen, nummerierte Dateien umzubenennen:

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

Eine andere Möglichkeit basierend auf rename

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

befehl

paste file1 file2

ausgabe

/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