Saya punya dua file. Satu file, saya kira, adalah bagian dari yang lain. Apakah ada cara untuk membedakan file-file untuk mengidentifikasi (secara ringkas) di mana pada file pertama file kedua cocok?
Apakah maksud Anda baris dari satu file adalah yang berikutnya, atau sebenarnya substring yang berdekatan?
Kaz
Substring yang berdekatan, @Kaz.
Richard
Jawaban:
14
diff -e bigger smaller akan melakukan trik, tetapi memerlukan beberapa interpretasi, karena hasilnya adalah "skrip ed yang valid".
Saya membuat dua file, "lebih besar" dan "lebih kecil", di mana isi "lebih kecil" identik dengan baris 5 hingga 9 dari "lebih besar" yang melakukan `beda-lebih besar lebih kecil" membuat saya:
% diff -e bigger smaller
10,15d
1,4d
Yang berarti "hapus baris 10 hingga 15 dari 'lebih besar', dan kemudian hapus baris 1 hingga 4, untuk mendapatkan 'lebih kecil'". Itu berarti "lebih kecil" adalah garis 5 sampai 9 dengan "lebih besar".
Membalikkan nama file memberi saya sesuatu yang lebih rumit. Jika "lebih kecil" benar-benar merupakan subset dari "lebih besar", hanya perintah 'd' (untuk dihapus) yang akan muncul di output.
Anda dapat melakukan ini secara visual dengan berbaur . Sayangnya, ini adalah alat GUI tetapi jika Anda hanya ingin melakukan ini sekali saja, dan pada file yang relatif kecil, itu akan baik-baik saja:
Apa yang 777harus dilakukan Saya menganggap Anda melewati NULL $/tetapi mengapa? Juga karena ini adalah saklar yang agak esoteris, penjelasan akan lebih baik untuk orang-orang non-perl.
terdon
1
@terdon saya memang melakukannya untuk menyeruput seluruh file. Penjelasan ditambahkan.
Joseph R.
Tetapi mengapa itu perlu? $a=<$fh>haruskah menyeruputnya kan?
terdon
1
@terdon Bukan yang saya tahu, tidak. Secara default $/diatur ke \nsehingga $a=<$fh>akan membaca hanya satu baris file $fhtelah dibuka. Kecuali perlperilaku baris perintah tentu saja memiliki standar yang berbeda yang saya tidak sadari?
Joseph R.
Argh, ya, salah saya, saya hampir tidak pernah menyeruput file atau menggunakan while $foo=<FILE>idiom jadi saya tidak yakin dan menjalankan tes (salah) yang tampaknya berhasil. Sudahlah :).
terdon
1
Jika file adalah file teks dan smaller, dalam biggermulai di awal baris, itu tidak terlalu sulit untuk diterapkan dengan awk:
Pertanyaan Anda adalah "Diff head of files". Jika Anda benar-benar bermaksud bahwa satu file adalah kepala dari yang lain, maka yang sederhana cmpakan memberi tahu Anda bahwa:
cmp big_file small_file
cmp: EOF on small_file
Itu memberi tahu Anda bahwa perbedaan antara dua file tidak terdeteksi sampai akhir file tercapai saat membaca small_file.
Namun, jika Anda maksudkan bahwa seluruh teks file kecil dapat terjadi di mana saja di dalam big_file, maka dengan asumsi Anda dapat memuat kedua file dalam memori, Anda dapat menggunakan
perl -le '
use autodie;
undef $/;
open SMALL, "<", "small_file";
open BIG, "<", "big_file";
$small = <SMALL>;
$big = <BIG>;
$pos = index $big, $small;
print $pos if $pos >= 0;
'
Ini akan mencetak offset di big_filemana konten small_fileberada (mis. 0 jika small_filecocok di awal big_file). Jika small_filetidak cocok di dalam big_file, maka tidak ada yang akan dicetak. Jika ada kesalahan, status keluar akan menjadi nol.
Jawaban:
diff -e bigger smaller
akan melakukan trik, tetapi memerlukan beberapa interpretasi, karena hasilnya adalah "skrip ed yang valid".Saya membuat dua file, "lebih besar" dan "lebih kecil", di mana isi "lebih kecil" identik dengan baris 5 hingga 9 dari "lebih besar" yang melakukan `beda-lebih besar lebih kecil" membuat saya:
Yang berarti "hapus baris 10 hingga 15 dari 'lebih besar', dan kemudian hapus baris 1 hingga 4, untuk mendapatkan 'lebih kecil'". Itu berarti "lebih kecil" adalah garis 5 sampai 9 dengan "lebih besar".
Membalikkan nama file memberi saya sesuatu yang lebih rumit. Jika "lebih kecil" benar-benar merupakan subset dari "lebih besar", hanya perintah 'd' (untuk dihapus) yang akan muncul di output.
sumber
Anda dapat melakukan ini secara visual dengan berbaur . Sayangnya, ini adalah alat GUI tetapi jika Anda hanya ingin melakukan ini sekali saja, dan pada file yang relatif kecil, itu akan baik-baik saja:
Gambar di bawah ini adalah output dari
meld a b
:sumber
vimdiff
, yang tersedia di terminal.Jika file-file tersebut cukup kecil, Anda dapat menyerupkan keduanya ke Perl dan minta mesin regex-nya melakukan trik:
The
-0777
beralih menginstruksikan Perl untuk mengatur pemisah record input$/
dengan nilai terdefinisi sehingga file slurp sepenuhnya.sumber
777
harus dilakukan Saya menganggap Anda melewati NULL$/
tetapi mengapa? Juga karena ini adalah saklar yang agak esoteris, penjelasan akan lebih baik untuk orang-orang non-perl.$a=<$fh>
haruskah menyeruputnya kan?$/
diatur ke\n
sehingga$a=<$fh>
akan membaca hanya satu baris file$fh
telah dibuka. Kecualiperl
perilaku baris perintah tentu saja memiliki standar yang berbeda yang saya tidak sadari?while $foo=<FILE>
idiom jadi saya tidak yakin dan menjalankan tes (salah) yang tampaknya berhasil. Sudahlah :).Jika file adalah file teks dan
smaller
, dalambigger
mulai di awal baris, itu tidak terlalu sulit untuk diterapkan denganawk
:sumber
Pertanyaan Anda adalah "Diff head of files". Jika Anda benar-benar bermaksud bahwa satu file adalah kepala dari yang lain, maka yang sederhana
cmp
akan memberi tahu Anda bahwa:Itu memberi tahu Anda bahwa perbedaan antara dua file tidak terdeteksi sampai akhir file tercapai saat membaca
small_file
.Namun, jika Anda maksudkan bahwa seluruh teks file kecil dapat terjadi di mana saja di dalam
big_file
, maka dengan asumsi Anda dapat memuat kedua file dalam memori, Anda dapat menggunakanIni akan mencetak offset di
big_file
mana kontensmall_file
berada (mis. 0 jikasmall_file
cocok di awalbig_file
). Jikasmall_file
tidak cocok di dalambig_file
, maka tidak ada yang akan dicetak. Jika ada kesalahan, status keluar akan menjadi nol.sumber