2016-08-01 64 views
0

從製表符分隔的文件中刪除行我有一個製表符分隔文件,第1列是一個ID,第2列是信息。我有第二個文件,其中包含需要從第一個文件中刪除的ID列表。當我使用grep時,我要麼獲得沒有更改的第一個文件的副本,要麼使用帶有-F -f「file2.txt」標誌/參數的-v獲得空白文件。 我的問題是:如何使用file2.txt比較它與file1的ID,以便從file1中刪除那些行以輸出到file3。使用grep -v

awk 'BEGIN{RS=">"}NR>1{sub("\n","\t"); gsub("\n",""); print RS$0}' $1 > fasta.tab 
grep -F -f $2 fasta.tab -v >rmOutput.tab 
tr '\t' \n' <rmOutput.tab >rmOutput.fas 
echo Runtime Complete 

線路1:創建一個從輸入端2 1 行製表DELIM文件:檢查輸入2爲比賽和刪除這些來自制表DELIM文件 第3行:重新創建輸入1 (爲了清楚起見)的格式

編輯:樣品I/O

輸入1(製表DELIM - 後第1行):

ID1 Info1 
ID2 Info2 
ID3 Info3 
ID4 Info4 
ID5 Info5 

輸入2(IDS被刪除):

ID2 
ID4 
ID5 

所需的輸出(從2號線)

ID1 Info1 
ID3 Info3 
+0

問題頂部的awk + ​​grep + tr + echo shell腳本的要點是什麼?你也提到'2號線後面'和類似的東西,但它不完全清楚這與你的樣本輸入/輸出有什麼關係 - 澄清這一點。 –

+0

輸入文件是一個序列文件。這是格式 > SeqID 序列 等 重點是將文件變成一個大的製表符delim文件。這是給我的腳本,所以我不確定它是否是最有效/最實用的。 –

+0

你是說你發佈的示例輸入實際上不是你必須處理的輸入格式嗎? –

回答

0
awk 'NR==FNR{a[$0];next} !($1 in a)' input2 input1 
0

如果沒有太多不同的ID刪除,在一個簡單的循環運行,removing lines inline with sed

# bash 
cp file1.txt out_file.txt 
for rem in `cat file2.txt` 
do 
    echo $rem 
    sed -i "/$rem/d" out_file.txt 
done 

#fish 
cp file1.txt out_file.txt 
for rem in (cat file2.txt) 
    echo $rem 
    sed -i "/$rem/d" out_file.txt 
end 

PS

預計一些火焰來自人們用神祕的bash過程替換和笨拙的awk腳本,讓我說: 事實上,你不應該用這個非常簡單和愉快的算法來讀取,如果你有很多不同的ID去除, 然而,根據The Holy Unix Philosophy Principles

  1. 花式算法比簡單算法緩慢,而且實現起來要困難得多。使用簡單的算法以及簡單的數據結構。 (三)羅布·派克

而且更重要的一個:

清晰的規則:淨度比聰明更好。

因爲維護太重要了,所以編寫程序就好像他們所做的最重要的溝通不是執行它們的計算機,而是面向未來將閱讀和維護源代碼的人(包括你自己)。

而且我還會添加一個包含fish代碼的片段。

+0

閱讀[使用shell-loop-to-process-text-considered-bad-practice](http://unix.stackexchange.com/questions/169716/why-is-using-a- shell-loop-to-process-text-considered-bad-practice)來理解你永遠不應該這樣做的一些原因,但不是全部。 –

+0

輸入文件1可以是從20到1200行的任何地方,輸入2是從1到任何輸入1是-1的任何值。 –

+0

@MichaelBale很好,那麼這對循環來說太過分了。 – xealits