2016-08-01 65 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