Tôi có hai tập tin. Một tập tin, tôi nghi ngờ, là một tập hợp con khác. Có cách nào để khuếch tán các tập tin để xác định (một cách cô đọng) trong tập tin thứ nhất tập tin thứ hai không?
Tôi có hai tập tin. Một tập tin, tôi nghi ngờ, là một tập hợp con khác. Có cách nào để khuếch tán các tập tin để xác định (một cách cô đọng) trong tập tin thứ nhất tập tin thứ hai không?
Câu trả lời:
diff -e bigger smaller
sẽ thực hiện thủ thuật, nhưng yêu cầu một số giải thích, vì đầu ra là "tập lệnh ed hợp lệ".
Tôi đã tạo hai tệp "lớn hơn" và "nhỏ hơn", trong đó nội dung của "nhỏ hơn" giống hệt với dòng 5 đến 9 của "lớn hơn" khi thực hiện `diff -e lớn hơn nhỏ hơn" cho tôi:
% diff -e bigger smaller
10,15d
1,4d
Có nghĩa là "xóa các dòng 10 đến 15 của 'lớn hơn', và sau đó xóa các dòng từ 1 đến 4, để có được 'nhỏ hơn'". Điều đó có nghĩa là "nhỏ hơn" là dòng 5 đến 9 của "lớn hơn".
Đảo ngược tên tập tin đã cho tôi một cái gì đó phức tạp hơn. Nếu "nhỏ hơn" thực sự tạo thành một tập hợp con "lớn hơn", chỉ các lệnh 'd' (để xóa) sẽ hiển thị trong đầu ra.
Bạn có thể làm điều này trực quan với meld . Thật không may, nó là một công cụ GUI nhưng nếu bạn chỉ muốn làm điều này một lần và trên một tệp tương đối nhỏ, nó sẽ ổn:
Hình ảnh dưới đây là đầu ra của meld a b
:
vimdiff
, có sẵn trong thiết bị đầu cuối.
Nếu các tệp đủ nhỏ, bạn có thể nhét cả hai vào Perl và để công cụ regex của nó thực hiện thủ thuật:
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";
'
Công -0777
tắc hướng dẫn Perl thiết lập dấu tách bản ghi đầu vào của nó $/
thành giá trị không xác định để làm mờ hoàn toàn các tệp.
777
làm gì? Tôi nhận nó bạn đang vượt qua NULL như $/
tại sao? Ngoài ra vì đây là những công tắc bí truyền, nên một lời giải thích sẽ tốt cho những người không phải là người perl.
$a=<$fh>
Dù sao cũng nên nhếch nhác phải không?
$/
là thiết lập để \n
sao cho $a=<$fh>
có thể chỉ đọc một dòng của tập tin $fh
đã được mở ra cho. Trừ khi perl
hành vi dòng lệnh của khóa học có các mặc định khác nhau mà tôi không biết?
while $foo=<FILE>
thành ngữ này vì vậy tôi không chắc chắn và đã chạy một bài kiểm tra (sai) có vẻ hiệu quả. Đừng bận tâm :).
Nếu các tệp là tệp văn bản và smaller
, bigger
bắt đầu ở đầu dòng, không quá khó để thực hiện với 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
Câu hỏi của bạn là "Diff head of files". Nếu bạn thực sự muốn nói rằng một tệp là đầu của tệp kia, thì một đơn giản cmp
sẽ cho bạn biết rằng:
cmp big_file small_file
cmp: EOF on small_file
Điều đó cho bạn biết rằng không tìm thấy sự khác biệt giữa hai tệp cho đến khi đạt đến cuối tệp trong khi đọc small_file
.
Tuy nhiên, nếu bạn có nghĩa là toàn bộ văn bản của tệp nhỏ có thể xảy ra ở bất kỳ đâu bên trong big_file
, thì giả sử bạn có thể vừa cả hai tệp trong bộ nhớ, bạn có thể sử dụng
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;
'
Điều này sẽ in phần bù trong big_file
đó vị trí của nội dung small_file
(ví dụ 0 nếu small_file
khớp ở đầu big_file
). Nếu small_file
không khớp bên trong big_file
thì sẽ không có gì được in. Nếu có lỗi, trạng thái thoát sẽ khác không.