web-dev-qa-db-ja.com

2つのファイルを行ごとに一貫してマージする方法

2つのファイルがあります(file1.txtfile2.txt)、ファイルは単なる例です。

ファイルを作成するために2つのファイルをマージする方法-merge_files.txt例3

私は今kshスクリプトを書いているので、マージはksh、awk、sed、Perl one liner ...などで行うことができます

背景-ファイルをマージする必要がある理由:私のターゲットはOLDファイル(最初のフィールドに存在する)の名前をNEWファイル(存在する2番目のフィールド)、

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

例2

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

例3

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

 first field                           second field

 OLD file                              NEW file
63
user1121951

pasteを使用して、ファイルを並べてフォーマットできます。

$ 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

例えば。:

$ 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

もちろん、いくつかの安全性チェック([ -f "${from}" ]、...)をスローする必要があります。

免責事項:ファイル名にスペースがない場合にのみ機能します。

114

このPerlワンライナーは、必要な名前の変更を表示します

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

これがうまくいく場合は、printステートメントを実際の名前に置き換えて使用します

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

実際の名前変更を行う

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

この仕事に最適です。ただし、Windows環境でテキストファイルを処理し、GNU貼り付けを使用する場合は、ファイルをUnix形式(CR)に変換し、(CR-LF)を使用しないでください。

GNUペーストはDOS形式を適切に処理していないようであり、解析は予測不能であり、予想される出力は不安定で、警告なしで予期しないものです。

GVIMを使用して簡単に変換できます(編集/ファイル設定/ファイル形式)

2
migs

番号付きファイルの名前を変更するというOPの目標を達成するためのまったく無関係な方法:

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

renameに基づく別の可能性

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

コマンド

paste file1 file2

出力

/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