2016-08-18 28 views
1

即時試圖對下列組線進行替換特定數目更改圖案:sed的 - 與數字

1AA20160817BBBBBDIGITS1NUMBER1STYLE59  00002200000220 
1AA20160817BBBBBDIGITS2NUMBER1STYLE60  00000000000220 
1AA20160817DDDDDDIGITS3NUMBER2STYLE60  00000000000486 
1AA20160817DDDDDDIGITS4NUMBER2STYLE59  00004860000486 
1AA20160817FFFFFDIGITS5NUMBER3STYLE602523111100000000000000 
1AA20160817FFFFFDIGITS6NUMBER3STYLE59  00000820000000 

我想要的最終輸出是這樣的:

1AA20160817BBBBBDIGITS1NUMBER1STYLE59  00002200000220 
1AA20160817BBBBBDIGITS1NUMBER1STYLE60  00000000000220 
1AA20160817DDDDDDIGITS3NUMBER2STYLE60  00000000000486 
1AA20160817DDDDDDIGITS3NUMBER2STYLE59  00004860000486 
1AA20160817FFFFFDIGITS5NUMBER3STYLE602523111100000000000000 
1AA20160817FFFFFDIGITS5NUMBER3STYLE59  00000820000000 

的變化是一個數字,就在每個第二行的「數字」之前。 BBBBB/DDDDD風格的模式是時間,最後一個字符是秒指示器。

我想它來檢查字符的具體數量和那裏執行變化,我已經寫了sed的做任務和其他具有類似:

sed -i.bak "s/^\(.\{1\}\)$scenario$datein\(.\{6\}\)$pod/1$scenario$datein$timein$pod/g" $1 

的代碼的其餘部分是在Perl。你們中的一個能幫我在Perl中做同樣的替換嗎?或者也許告訴我如何從Perl代碼運行此sed命令?我的問題是有問題的文件是巨大的,並且bash花費太長的時間讀取每一行,並執行替換。提前致謝。在substr

+3

就是第一塊和第二之間的區別做呢?對我來說,他們看起來相同 – fedorqui

+2

噢,不僅僅是我...... :) – Sobrique

+0

每個第二個塊都有一個不同的字符,就在「數字」之前 – onlyf

回答

0

更新  整理了發言,其中提到了要「」,銘記發佈數據 - substr適用於字符串。用更好的方法替換魔術22以找到偏移量。


您可以通過查看$.確定偶數和奇數行 - 從(最近訪問)的文件句柄讀取當前的行號。看到它in perlvar

use warnings; 
use strict; 

my $set_num_to = 0; 

while (<DATA>) 
{ 
    if ($. % 2 != 0) { # odd line number 
     ($set_num_to) = $_ =~ m/(\d)NUMBER/; 
     print; 
    } 
    else { 
     s/\d(?=NUMBER)/$set_num_to/; 
     print; 
    } 
} 

__DATA__ 
1AA20160817BBBBBDIGITS1NUMBER1STYLE59  00002200000220 
1AA20160817BBBBBDIGITS2NUMBER1STYLE60  00000000000220 
1AA20160817DDDDDDIGITS3NUMBER2STYLE60  00000000000486 
1AA20160817DDDDDDIGITS4NUMBER2STYLE59  00004860000486 
1AA20160817FFFFFDIGITS5NUMBER3STYLE602523111100000000000000 
1AA20160817FFFFFDIGITS6NUMBER3STYLE59  00000820000000 

正則表達式使用字符串NUMBER,如在實施例和對缺乏更具體的給定的,以識別數字給奇數行,然後將其用於代替在上甚至相同的位置上的一個取線。它使用positive lookahead,(?=PATTERN)。如果替換被認爲是比當前數目較少(而不是從前面的行號)之一,則可以使用

s/(\d)(?=NUMBER)/$1-1/e if $. % 2 == 0; 

/e改性劑使得第一替換側進行評估,然後的結果用作替代品。見perlopthis post

人們可以使用substr代替,如果位置固定

my $offset = length '1AA20160817BBBBBDIGITS'; 

while (<DATA>) 
{ 
    if ($. % 2 != 0) { 
     # Retrieve substring of length 1 at given offset 
     $set_num_to = substr $_, $offset, 1; 
    } 
    else { 
     # Replace substring of same length at same offset by one captured above 
     substr $_, $offset, 1, $set_num_to; 
    } 
} 

其餘部分是相同的,並打印線的規定。

同樣,如果您需要從中減去1而不是用前一行中的數字替換它,則可以在$. % 2 == 0條件中使用上面的兩行。

2

假設輸入數據是data.txt

$ perl -i -pe's/(\d)(?=NUMBER)/$1-1/e if ! ($. % 2)' data.txt 
  • -i:編輯輸入文件就地和創建備份
  • -p:運行這段代碼的代碼輸入和打印每行$ _每次迭代
  • -e:要運行的代碼
  • s/(\d)(?=NUMBER)/$1-1/e:尋找數字後面通過「NUMBER」主編,並與一個來自數字
  • ​​減去替換它:但只爲偶數記錄