回答:
diff -e bigger smaller
トリックを実行しますが、出力は「有効なedスクリプト」であるため、ある程度の解釈が必要です。
「bigger」と「smaller」の2つのファイルを作成しました。「smaller」の内容は、「diff -e bigger small」を実行する「bigger」の5〜9行目と同じです。
% diff -e bigger smaller
10,15d
1,4d
これは、「 'bigger'の10行目から15行目を削除してから、1行目から4行目を削除して 'smaller'にすることを意味します。つまり、「小さい」は「大きい」の5行目から9行目です。
ファイル名を逆にすると、さらに複雑になります。「小さい」が「大きい」のサブセットを本当に構成している場合、「d」(削除)コマンドのみが出力に表示されます。
ファイルが十分に小さい場合、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を指示する$/
完全SLURPファイルするように未定義の値に。
777
ますか?私はあなたがNULLを渡していると思いますが$/
、なぜですか?また、これらはちょっと難解なスイッチなので、Perl以外の人には説明がいいでしょう。
$a=<$fh>
とにかく右に丸呑みする必要がありますか?
$/
は、ファイルの1行のみが読み取られる\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
あなたの質問は「Diff head of files」です。1つのファイルが他のファイルの先頭であることを本当に意味している場合は、単純なファイルでそれcmp
がわかります。
cmp big_file small_file
cmp: EOF on small_file
これは、の読み取り中にファイルの終わりに達するまで、2つのファイルの違いが検出されなかったことを示してい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
が配置されている場所内のオフセットを出力します(たとえばsmall_file
、の先頭に一致する場合は0 big_file
)。small_file
内部big_file
で一致しない場合、何も印刷されません。エラーがある場合、終了ステータスはゼロ以外になります。