2013-08-03 47 views
2

我有例如兩個文件的Perl:輸入文件數據到另一個文件的當前位置

文件1

abcd 

文件2

this is test 
it is abcd but 

我想在

之間添加ABCD

OUTPUT

this is test 
abcd 
it is abcd but 

我能夠使用正則表達式來比較文件1與文件2,並得到postition其中文件1含量等於文件2線

喜歡這裏。「ABCD」包含在「這是ABCD,而是」

但怎麼辦我在上面添加abcd?這僅僅是一個例子。我的真實文件非常大。我很感激你是否可以幫助我開發通用腳本來與其他文件一起使用。

+0

只是爲了確認,**文件1 **和** ** file2的都有很多線路的,對不對?因爲它看起來像** file1 **在你給出的例子中只有1行。 – doubleDown

+0

順便說一下,你可以發佈你用來比較file1和file2與正則表達式的代碼嗎? – doubleDown

+0

@doubleDown毫無疑問,沒有人會發佈一個如此具有誤導性的問題。這就像是......「我如何關掉燈......」和「......在紐約市?」之間的區別。 – TLP

回答

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; 
} 
+0

你的oneliner似乎不起作用,我測試過,輸出包含兩個'abcd'行,然後是預期的輸出。 – cuonglm

+0

是的,這是不首先測試它的缺點。但是,再一次,這只是向你展示一種繼續前進的方式。我們需要使用'-n'開關,而不是打印第一行。 – TLP

-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; 
    } 
} 
相關問題