我有一個看起來像這樣的大檔案:
esup_255_3 transdecoder 7655 8192
esup_6093_1 transdecoder 2732 2774
esup_25727_1 transdecoder 1 60
...
第 3 列和第 4 串列示數字的間隔。
我正在嘗試修改此檔案以使間隔內包含的數字串列列在不同的列(此處為第 5 列)中,如下所示:
esup_255_3 transdecoder 7655 8192 7655
esup_255_3 transdecoder 7655 8192 7656
esup_255_3 transdecoder 7655 8192 7657
esup_255_3 transdecoder 7655 8192 ...
esup_255_3 transdecoder 7655 8192 8192
esup_6093_1 transdecoder 2732 2774 2732
esup_6093_1 transdecoder 2732 2774 2733
esup_6093_1 transdecoder 2732 2774 ....
esup_6093_1 transdecoder 2732 2774 2774
... and so on...
我認為 Perl 可能對此有所幫助,但我對它很陌生。我只精通bash,在這里我似乎找不到正確的方法來獲得我需要的東西。
uj5u.com熱心網友回復:
像這樣的東西?
perl -lne 'my ($line, $from, $to) = /^(.*\s(\d )\s (\d )\s*)$/; print "$line\t$_" for $from..$to;'
當我在您的代碼段上運行它時,它會列印出 641 行:
esup_255_3 transdecoder 7655 8192 7655
esup_255_3 transdecoder 7655 8192 7656
esup_255_3 transdecoder 7655 8192 7657
[...]
esup_255_3 transdecoder 7655 8192 8190
esup_255_3 transdecoder 7655 8192 8191
esup_255_3 transdecoder 7655 8192 8192
esup_6093_1 transdecoder 2732 2774 2732
esup_6093_1 transdecoder 2732 2774 2733
[...]
esup_6093_1 transdecoder 2732 2774 2773
esup_6093_1 transdecoder 2732 2774 2774
esup_25727_1 transdecoder 1 60 1
esup_25727_1 transdecoder 1 60 2
[...]
esup_25727_1 transdecoder 1 60 59
esup_25727_1 transdecoder 1 60 60
下面是一個解釋。讓我們從選項開始:
perl -lne
我們將把它們從右到左。( -efor "execute" or "evaluate") 只是告訴 Perl 命令列上的下一件事是要運行的代碼,因此它不會在標準輸入上查找代碼。
-n告訴它自動逐行迭代其輸入;它的作用就好像在實際代碼周圍有一個while (<>) {...回圈。}在回圈體內,當前行將在主題變數中找到$_。
告訴它從-l輸入中去除換行符,并自動將一個換行符附加到列印出的每個字串;這基本上消除了換行符并簡化了邏輯。
因此,程式將逐行讀取輸入并運行-e在每一行作為引數給出的代碼。讓我們看一下以這條陳述句開頭的代碼:
my ($line, $from, $to) = /^(.*\s(\d )\s (\d )\s*)$/;
正則運算式沒有要匹配的顯式字串,因此它會自動匹配$_具有當前行的 。它必須匹配整行(因為^在開頭和$結尾)。由于最外面的括號,實際的行值也被捕獲,因此它將是匹配回傳的第一項,它被分配給變數$line。
該行的第一部分可以是任何東西(因為.*匹配所有東西),所以我們真正關注的是字串的結束方式而不是它的開始方式。第一項感興趣的是任何空白字符 ( \s),這是為了確保我們不會錯過以下任何數字。具體來說,我們正在尋找\d 括號捕獲的一個或多個數字 ( ),因此匹配也將回傳該值;這是第二次捕獲,所以它進入分配中的第二個變數,$from. 在這些數字之后,我們尋找更多的空格(至少需要一個空格字符,但允許任何數字),然后是另一個數字序列;第二組數字再次被捕獲并回傳,所以它在最后一個變數中結束,$to. 最后,我們允許最后一組數字后跟任意數量的可選尾隨空格。
因此,在閱讀您的第一行之后$_ = "esup_255_3 transdecoder 7655 8192 ",匹配 賦值將設定$line為整個字串的副本$fromto7655和$toto 8192。
然后我們來到輸出。這一行:
print "$line\t$_" for $from .. $to;
是撰寫此回圈的一種更短的方式:
foreach $_ ($from .. $to) {
print "$line\t$_";
}
$from這意味著它回圈從到的整數$to,作為回圈控制變數重用$_(這就是我們必須將當前行復制到的原因$line)。對于范圍內的每個值,它會列印出整行的副本,后跟一個制表符和當前數字。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/478972.html
上一篇:如何替換用雙引號括起來的值
下一篇:Perl-子字串關鍵字
