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?
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?
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:
% 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:
Gambar di bawah ini adalah output dari meld a b
:
vimdiff
, yang tersedia di terminal.
Jika file-file tersebut cukup kecil, Anda dapat menyerupkan keduanya ke Perl dan minta mesin regex-nya melakukan trik:
perl -0777e '
open "$FILE1","<","file_1";
open "$FILE2","<","file_2";
$file_1 = <$FILE1>;
$file_2 = <$FILE2>;
print "file_2 is", $file_1 =~ /\Q$file_2\E/ ? "" : "not";
print " a subset of file_1\n";
'
The -0777
beralih menginstruksikan Perl untuk mengatur pemisah record input $/
dengan nilai terdefinisi sehingga file slurp sepenuhnya.
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. Kecuali perl
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
, dalam bigger
mulai di awal baris, itu tidak terlalu sulit untuk diterapkan dengan awk
:
awk -v i=0 'NR==FNR{l[n++]=$0;next}
{if ($0 == l[i]) {if (++i == n) {print FNR-n+1;exit}} else i=0}
' smaller bigger
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:
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_file
mana konten small_file
berada (mis. 0 jika small_file
cocok di awal big_file
). Jika small_file
tidak cocok di dalam big_file
, maka tidak ada yang akan dicetak. Jika ada kesalahan, status keluar akan menjadi nol.