我想使用 grep 將行之間的所有行從一個文件複製到另一個文件,/protein_id=
直到顯示的蛋白質序列末尾。例如,從此輸入:
CDS 448..1269
/gene="nptII"
/note="neomycin phosphotransferase II"
/codon_start=1
/product="kanamycin resistance protein"
/protein_id="AAQ05967.1"
/db_xref="GI:33320494"
/translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"
regulatory 1443..2148
我想要這個輸出:
/protein_id="AAQ05967.1"
/db_xref="GI:33320494"
/translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"
請注意,輸入可能會有所不同,因為以 開頭的行regulatory
可以替換為其他內容。不變的是序列以大寫字母給出並以 結尾"
。用grep可以嗎?
答案1
pcregrep
是一個使用 perl 5 相容正規表示式的 grep 實用程式。 Perl 風格的正規表示式具有許多標準 POSIX 正規表示式所沒有的有用功能。這與 grep 基本相同,但具有不同的正規表示式語法。
sudo apt-get install pcregrep
pcregrep -M .*'/protein_id=.*(\n|.)*\"' path/to/input-file
/protein_id
是起始搜尋詞,"
是結束搜尋詞。
以下是對起始搜尋項目和結束搜尋項目之間的所有行進行多行搜尋的命令的通用範例:
pcregrep -M .*'START-SEARCH-TERM.*(\n|.)*END-SEARCH-TERM' path/to/SOURCE-FILE >> path/to/DESTINATION-FILE
在哪裡:
- SOURCE-FILE 是包含您的資料的文件
- DESTINATION-FILE 是將結果複製到的文件
- START-SEARCH-TERM 是開始搜尋字詞
- END-SEARCH-TERM 是結束搜尋詞
-M, --multiline
允許模式匹配多行。
答案2
不,grep
不能跨多行匹配。您可以使用pcregrep
@karel 所示的方法來完成此操作,但不能使用 pure grep
。相反,由於您知道蛋白質序列始終為大寫且以 結尾"
,因此您可以匹配:
sed
sed -n '/\/protein_id=/,/^\s*[[:upper:]]\+"\s*$/{p}' two_seq.txt
此
sed
模式的/foo/,/bar/{p}
意思是「列印foo
和之間的所有行bar
。-n
抑制正常輸出,因此僅列印請求的行。請注意,/
需要/protein_id=
轉義 (\/
),因為它/
是匹配運算符的一部分。第二個模式有點複雜,它在行的開頭查找0 個或多個空格 (^\s*
),然後查找一個或多個大寫字母,後跟雙引號 ([[:upper:]]"
),然後查找 0 個或多個空白字符,直到行尾 (\s*$
)。珀爾
perl -ne 'print if m#/protein_id=# ... m#[A-Z]+"\s*$#' file.flat
這裡的想法相同,
...
操作符指定一個範圍並列印兩個模式之間的線。awk
awk '/\/protein_id=/{a=1}; a==1{print} /^\s*[[:upper:]]+"\s*$/{a=0}' file.flat
在這裡,我們將變數設定
a
為該1
行是否與第一個模式相符以及0
是否與最後一個模式相符。然後,我們告訴awk
列印 ifa
is1
。由於第二個模式print
的“之前呼叫”a
設定為0
,因此這也將包括包含第二個模式的行。