2

例如,我有两个文件

文件 1

abcd

文件2

this is test
it is abcd but

我想在两者之间添加 abcd

输出

this is test
abcd
it is abcd but

我能够使用正则表达式将 file1 与 file2 进行比较,并获得 file1 内容等于 file2 行的位置

像这里 .."abcd" 包含在 "it is abcd but" 中

但是我如何在它上面添加 abcd?这只是一个例子。我的实际文件很大。如果您能帮助我开发通用脚本以与其他文件一起使用,我将不胜感激。

4

2 回答 2

3

这浮现在脑海中(未经测试):

perl -nlwe 'if (defined($ab)) { s/^(?=.*$ab)/$ab\n/; print; }
            else { $ab = quotemeta($_); }' file1 file2

解释:

开关:

  • -p读取文件和打印行
  • -l处理换行符

所以首先,我们从 中获取行file1,它存储在$ab. 因为我们使用定义或赋值,所以我们只得到第一个值,它来自file1. 我们quotemeta()用来禁用元字符。然后我们只需用正则表达式检查每一行,如果出现单词,我们首先在该行添加它,然后是换行符。正则表达式使用行首锚点^将插入点设置在行首。然后我们使用前瞻断言来确保该行包含该单词。

这是脚本版本:

use strict;
use warnings;

$\ = "\n";                 # output field separator 
my $ab;
while (<>) {               # read argument files
    chomp;                 # remove newline
    $ab //= quotemeta($_); # set $ab
    s/^(?=.*$ab)/$ab\n/;   # perform substitution
}
continue {
    print;
}
于 2013-08-03T18:27:53.563 回答
-1

这是我的解决方案。

每一行都保存到 $prev。当下一行匹配 /$match/ 并且有上一行 $prev 时,打印 $match,然后将当前行分配给最后一行变量。

单线:

perl -nle 'if (defined($m)) {/$m/ and $prev and print $m;$prev=$_;print} 
           else { $m = quotemeta($_) }' file1 file2

脚本:

#!/usr/bin/env perl

use v5.14;

open FH_ONE, '<', 'file1'
    or die "Can not open: $!";

open FH_TWO, '<', 'file2'
    or die "Can not open: $!";

while (<FH_ONE>) {
    chomp;
    my $match //= quotemeta($_);
    my $prev;

    while (<FH_TWO>) {
        chomp;
        say $match if /$match/ and $prev;
        $prev = $_;
        say;
    }
}
于 2013-08-03T19:14:38.837 回答