Saya telah membaca tentang diff dan patch tetapi saya tidak tahu bagaimana menerapkan apa yang saya butuhkan. Saya kira ini cukup sederhana, jadi untuk menunjukkan masalah saya ambil dua file ini:
a.xml
<resources>
<color name="same_in_b">#AAABBB</color>
<color name="not_in_b">#AAAAAA</color>
<color name="in_b_but_different_val">#AAAAAA</color>
<color name="not_in_b_too">#AAAAAA</color>
</resources>
b.xml
<resources>
<color name="same_in_b">#AAABBB</color>
<color name="in_b_but_different_val">#BBBBBB</color>
<color name="not_in_a">#AAAAAA</color>
</resources>
Saya ingin memiliki output, yang terlihat seperti ini (pesanan tidak masalah):
<resources>
<color name="same_in_b">#AAABBB</color>
<color name="not_in_b">#AAAAAA</color>
<color name="in_b_but_different_val">#BBBBBB</color>
<color name="not_in_b_too">#AAAAAA</color>
<color name="not_in_a">#AAAAAA</color>
</resources>
Penggabungan harus berisi semua baris di sepanjang aturan sederhana ini:
- setiap baris yang hanya ada di salah satu file
- jika suatu baris memiliki tag nama yang sama tetapi memiliki nilai yang berbeda, ambil nilainya dari yang kedua
Saya ingin menerapkan tugas ini di dalam skrip bash, jadi tidak perlu harus dilakukan dengan diff dan patch, jika program lain lebih cocok
diff
dapat memberi tahu Anda baris mana dalam satu file tetapi tidak pada yang lain, tetapi hanya pada rincian seluruh baris.patch
hanya cocok untuk membuat perubahan yang sama untuk file yang sama (mungkin versi berbeda dari file yang sama, atau file yang sama sekali berbeda di mana namun nomor baris dan garis sekitarnya untuk setiap perubahan identik dengan file asli Anda). Jadi tidak, mereka tidak cocok untuk tugas ini. Anda mungkin ingin melihatnyawdiff
tetapi solusinya mungkin memerlukan skrip khusus. Karena data Anda terlihat seperti XML, Anda mungkin ingin mencari beberapa alat XSL.Jawaban:
Anda tidak perlu
patch
untuk ini; itu untuk mengekstraksi perubahan dan mengirimkannya tanpa bagian file yang tidak berubah.Alat untuk menggabungkan dua versi file adalah
merge
, tetapi seperti yang@vonbrand
ditulis, Anda memerlukan file "basis" dari mana dua versi Anda berbeda. Untuk melakukan penggabungan tanpa itu, gunakandiff
seperti ini:Ini akan menyertakan setiap set perubahan dalam perintah C-style
#ifdef
/#ifndef
"preprocessor", seperti ini:Jika garis atau wilayah berbeda antara dua file, Anda akan mendapatkan "konflik", yang terlihat seperti ini:
Jadi simpan output dalam file, dan buka di editor. Cari tempat mana pun yang
#else
muncul, dan atasi secara manual. Kemudian simpan file dan jalankangrep -v
untuk menyingkirkan yang tersisa#if(n)def
dan#endif
baris:Di masa depan, simpan versi file asli.
merge
dapat memberi Anda hasil yang lebih baik dengan bantuan informasi tambahan. (Tapi hati-hati:merge
edit salah satu file di tempat, kecuali Anda menggunakan-p
. Baca manual).sumber
sed -e "s/^#else.*$/\/\/ conflict/g"
#else
baris secara manual, di editor selama resolusi konflik.merge(1)
mungkin lebih dekat dengan apa yang Anda inginkan, tetapi itu membutuhkan leluhur yang sama untuk dua file Anda.Cara (kotor!) Untuk melakukannya adalah:
grep(1)
untuk mengecualikan merekasort -u
meninggalkan daftar yang diurutkan, menghilangkan duplikatHumm ... sesuatu seperti itu:
echo '<resources>'; grep -v resources file1 file2 | sort -u; echo '</resources>'
mungkin lakukan.
sumber
name
in_b_but_different_val
memiliki nilai#00AABB
semacam akan menempatkan itu di atas dan menghapus nilai kedua alih-alih yang pertamadiff3
bekerja dengan cara yang sama. Membutuhkan file leluhur yang umum. Mengapa tidak ada alat CLI sederhana yang hanya menggabungkan 2 file bersama berdasarkan apa yangdiff
ditampilkan.sdiff
(1) - gabungan dari perbedaan fileGunakan
--output
opsi, ini akan secara interaktif menggabungkan dua file. Anda menggunakan perintah sederhana untuk memilih perubahan atau mengedit perubahan.Anda harus memastikan bahwa
EDITOR
variabel lingkungan diatur. Editor default untuk perintah seperti "eb" biasanyaed
, editor baris .sumber
vim
sebagai editor lebih baik. Tapi ini solusi terbaik, ia datang dengandiff
perintah juga!Di sini solusi sederhana yang berfungsi menggabungkan hingga 10 file :
harap perhatikan arg yang didahulukan memiliki prioritas sehingga Anda harus menelepon:
untuk mendapatkan nilai-nilai umum
b.xml
daria.xml
.script b.xml a.xml
beluk:sumber
Peretasan mengerikan lainnya - bisa disederhanakan, tetapi: P
sumber
OK, coba kedua, sekarang di Perl ( bukan kualitas produksi, tidak ada pengecekan!):
sumber
Yang lain, menggunakan cut and grep ... (mengambil a.xml b.xml sebagai argumen)
sumber
echo
adalah tindakan default, jadixargs echo
tidak perlu. Kenapa kau tidak melakukannyatr '\n' '|'
saja?