У меня есть два файла. Я подозреваю, что один файл является подмножеством другого. Есть ли способ различать файлы, чтобы определить (кратким образом), куда в первом файле помещается второй файл?
У меня есть два файла. Я подозреваю, что один файл является подмножеством другого. Есть ли способ различать файлы, чтобы определить (кратким образом), куда в первом файле помещается второй файл?
Ответы:
diff -e bigger smaller
сделает свое дело, но требует некоторой интерпретации, поскольку на выходе получается «действительный сценарий ed».
Я сделал два файла, «больше» и «меньше», где содержимое «поменьше» идентично строкам с 5 по 9 «больше», выполнив «diff -e большее поменьше»:
% diff -e bigger smaller
10,15d
1,4d
Что означает «удалить строки с 10 по 15« больше », а затем удалить строки с 1 по 4, чтобы получить« меньше »». Это означает, что «меньше» - это строки с 5 по 9 «больше».
Изменение имен файлов сделало меня чем-то более сложным. Если «поменьше» действительно составляет подмножество «побольше», то в выводе будут отображаться только команды «d» (для удаления).
Вы можете сделать это визуально с Meld . К сожалению, это инструмент с графическим интерфейсом, но если вы просто хотите сделать это один раз и для относительно небольшого файла, все будет хорошо:
Изображение ниже является выводом meld a b
:
vimdiff
, что доступно в терминале.
Если файлы достаточно малы, вы можете перетянуть их в Perl и сделать так, чтобы механизм их регулярных выражений сделал свое дело:
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 , чтобы установить свой входной разделитель записей $/
в неопределенное значение так, чтобы хлебать файлы полностью.
777
? Я так понимаю, вы передаете NULL, $/
но почему? Также, поскольку это своего рода эзотерические переключатели, объяснение было бы неплохо для людей, не относящихся к Perl.
$a=<$fh>
должно все равно хлебать, верно?
$/
установлено значение \n
так, что $a=<$fh>
при чтении $fh
была открыта только одна строка файла . Если, конечно, perl
поведение командной строки не имеет других значений по умолчанию, о которых я не знаю?
while $foo=<FILE>
идиомы, поэтому я не был уверен и провел (неправильный) тест, который, похоже, сработал. Ничего :).
Если файлы представляют собой текстовые файлы и 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
Ваш вопрос "Диффер глава файлов". Если вы действительно имеете в виду, что один файл является главой другого, то простой 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
, то ничего не будет напечатано. Если есть ошибка, статус выхода будет ненулевым.