2017-08-09 68 views
1

我正在使用fasta文件,並且需要爲每個標題添加行特定文本。因此,例如,如果我的文件是:使用while循環替換fasta文件中的某些行,並使用while循環和if/else語句

>TER1 
AGCATGCTAGCTAGTCGACTCGATCGCATGCTC 
>TER2 
AGCATGCTAGCTAGACGACTCGATCGCATGCTC 
>URC1 
AGCATGCTAGCTAGTCGACTCGATCGCATGCTC 
>URC2 
AGCATGCTACCTAGTCGACTCGATCGCATGCTC 
>UCR3 
AGCATGCTAGCTAGTCGACTCGATGGCATGCTC 

我想要一個while循環,將讀取每一行;對於開頭爲>的人,我想追加|population:加上>後面的前三個字符。所以線之一將是:

>TER1|population:TER 

我無法弄清楚如何使這項工作。這是迄今爲止我的最佳嘗試。

filename="testfasta.fa" 
while read -r line 
do 
    if [[ "$line" == ">"* ]]; then 
     id=$(cut -c2-4<<<"$line") 
     printf $line"|population:"$id"\n" >>outfile 
    else 
     printf $line"\n">>outfile 
    fi 
done <"$filename" 

這會生成一個文件,其中包含原始標題和每行下一行。 有人能告訴我我哪裏出錯了嗎?我的if和else循環根本不起作用! 謝謝!

+0

我已經編輯了您的代碼塊並刪除了空行,因爲我認爲您只是將它們放在那裏以獲得換行符,對不對?此外,您的循環對我來說也是如此。 –

+0

是Benjamin W.謝謝!我如何刪除空行? – user2414840

+0

對於正確的代碼塊,您必須縮進四個空格。選擇要編碼的代碼並使用{}按鈕或按下Ctrl-K。在代碼塊中,符合換行符。 –

回答

1

可以使用while循環,如果你真的想要, 但sed會更簡單:

sed -e 's/^>\(...\).*/&|population:\1/' "$filename" 

也就是說,開始>(模式:^>)線, 捕捉未來3字符(與\(...\)), 並匹配該行的其餘部分(.*), 用行替換(&), 和固定字符串|population:, 並最後捕獲3個字符(\1)。

這將產生您的輸入:

>TER1|population:TER 

AGCATGCTAGCTAGTCGACTCGATCGCATGCTC 

>TER2|population:TER 

AGCATGCTAGCTAGACGACTCGATCGCATGCTC 

>URC1|population:URC 

AGCATGCTAGCTAGTCGACTCGATCGCATGCTC 

>URC2|population:URC 

AGCATGCTACCTAGTCGACTCGATCGCATGCTC 

>UCR3|population:UCR 

AGCATGCTAGCTAGTCGACTCGATGGCATGCTC 

或者您可以使用此awk,也產生了相同的輸出:

awk '{sub(/^>.*/, $0 "|population:" substr($0, 2, 3))}1' "$filename" 
+0

謝謝janos這個工作得很好 – user2414840

1

可以在awk迅速做到這一點:

awk '$1~/^>/{$1=$1"|population:"substr($1,2,3)}{}1' infile.txt > outfile.txt 

$ awk '$1~/^>/{$1=$1"|population:"substr($1,2,3)}{}1' testfile 
>TER1|population:TER 

AGCATGCTAGCTAGTCGACTCGATCGCATGCTC 

>TER2|population:TER 

AGCATGCTAGCTAGACGACTCGATCGCATGCTC 

>URC1|population:URC 

AGCATGCTAGCTAGTCGACTCGATCGCATGCTC 

>URC2|population:URC 

AGCATGCTACCTAGTCGACTCGATCGCATGCTC 

>UCR3|population:UCR 

AGCATGCTAGCTAGTCGACTCGATGGCATGCTC 

這裏awk將:

  1. 測試,如果記錄與>$1開始着眼於第一場,但$0整個記錄將在這種情況下很好的工作。 ~將執行正則表達式測試,^>表示「從>開始」。進行測試:($1~/^>/
  2. 如果是這樣,它會將第一個字段設置爲您正在查找的輸出(使用substr()獲取所需字符串的位。{$1=$1"|population:"substr($1,2,3)}
  3. 最後它會打印出整個記錄(如果適用,進行更改):{}1這是{print $0}的簡寫或打印整個記錄。
+0

謝謝你們的快速建議。我選擇了sed。由於我還在學習unix,所以我很想知道,雖然我的乏味的while循環不起作用... – user2414840

+0

我會提供一些建議,但我發現在bash中做不同的方法來完成條件。我一直寫它們,而且他們從未嘗試過我的第一次嘗試。有一天我會弄清楚。當處理一個文件時,首先想到sed和awk。 Sed用於將文件作爲一個流,在流過時更改。 Awk用於處理記錄和字段(CSV,日誌文件和其他內容)。 – JNevill