Різна заголовок файлів


11

У мене два файли. Підозрюю, що один файл є підмножиною іншого. Чи є спосіб розрізнити файли, щоб визначити (стислим чином), де в першому файлі підходить другий файл?



Ви маєте на увазі, що рядки одного файлу є послідовністю іншого або насправді суміжним підрядком?
Каз

Суміжний підряд, @Kaz.
Річард

Відповіді:


14

diff -e bigger smaller зробить трюк, але вимагає певної інтерпретації, оскільки вихід - це "дійсний сценарій редагування".

Я зробив два файли, "більший" і "менший", де вміст "менший" ідентичний рядкам 5 - 9 "більший", що робить `diff -e більший менший", отримав мене:

% diff -e bigger smaller
10,15d
1,4d

Що означає "видалити рядки з 10 по 15 з" більшої ", а потім видалити рядки з 1 по 4, щоб отримати" менший "". Це означає, що "менший" - це рядки від 5 до 9 "більшої".

Зміна імен файлів отримала мені щось складніше. Якщо "менший" справді становить підмножину "більших", у висновку відображаються лише команди "d" (для видалення).


5

Зробити це можна візуально за допомогою монтажу . На жаль, це інструмент графічного інтерфейсу, але якщо ви просто хочете це зробити один раз, і на відносно невеликому файлі, це повинно бути добре:

Зображення нижче - це результат meld a b:

введіть тут опис зображення


1
Meld приємний, але він не дуже добре грає зі 100MB + файлами.
Річард

@Richard ні, це не так, і я все одно віддаю перевагу інструменту командного рядка, я просто думав, що це згадаю.
terdon

Схоже vimdiff, що доступно в терміналі.
Патрік

2

Якщо файлів достатньо мало, ви можете прив’язати їх як до Perl, так і його механізм regex зробити трюк:

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";
'

-0777Перемикач інструктує Perl , щоб встановити свій вхідний роздільник записів $/в невизначене значення так, щоб сьорбати файли повністю.


1
Що робить 777? Я вважаю, ти передаєш NULL як, $/але чому? Крім того, що це своєрідні езотеричні перемикачі, пояснення було б непоганим для людей, які не мають перлів.
terdon

1
@terdon Я справді роблю це, щоб вирвати файли цілими. Пояснення додано.
Джозеф Р.

Але для чого це потрібно? $a=<$fh>чи варто сіпатися все-таки так?
terdon

1
@terdon Не те, що я знаю, ні. За замовчуванням $/встановлено \nтак, що $a=<$fh>було $fhб відкрито лише один рядок файлу . Якщо, звичайно, perlповедінка командного рядка не має різних за замовчуванням, про які я не знаю?
Джозеф Р.

Аргу, так, мій поганий, я майже ніколи не балакаю файли і не використовую while $foo=<FILE>ідіому, тому я не був впевнений і провів (неправильний) тест, який, здавалося, спрацював. Не звертай уваги :).
terdon

1

Якщо файли - це текстові файли, і smaller, biggerпочинаючи з початку на початку рядка, реалізувати це не так вже й складно 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

1

Ваше запитання - "Різна заголовок файлів". Якщо ви дійсно маєте на увазі, що один файл є головою іншого, то простий cmpскаже вам, що:

cmp big_file small_file
cmp: EOF on small_file

Це говорить про те, що різниця між двома файлами не була виявлена, поки не було досягнуто кінця файлу під час читання small_file.

Якщо ви маєте на увазі, що весь текст невеликого файлу може зустрічатися в будь-якому місці всередині big_file, то, припускаючи, що ви можете помістити обидва файли в пам'яті, ви можете використовувати

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;
'

Це надрукує зміщення в межах, big_fileде знаходиться вміст small_file(наприклад, 0, якщо small_fileзбіг на початку big_file). Якщо small_fileвсередині не збігається big_file, то нічого не буде надруковано. Якщо є помилка, статус виходу буде не нульовим.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.