Awk 如何使用pipe同时使用grep和sed

Awk 如何使用pipe同时使用grep和sed,awk,sed,terminal,grep,Awk,Sed,Terminal,Grep,我有两个文件 文件1 TRINITY_DN10039_c1_g1_i1 216 Brassica rapa TRINITY_DN10270_c0_g1_i1 233 Pan paniscus TRINITY_DN10323_c0_g1_i2 209 Corynebacterium aurimucosum ATCC 700975 . . TRINITY_DN10462_c0_g1_i1 257

我有两个文件

文件1

TRINITY_DN10039_c1_g1_i1        216     Brassica rapa   
TRINITY_DN10270_c0_g1_i1        233     Pan paniscus  
TRINITY_DN10323_c0_g1_i2        209     Corynebacterium aurimucosum ATCC 700975  
.  
.   
TRINITY_DN10462_c0_g1_i1        257     Helwingia himalaica    
TRINITY_DN10596_c0_g1_i1        205     Homo sapiens   
TRINITY_DN10673_c0_g2_i2        323     Anaerococcus prevotii DSM 20548
文件2

TRINITY_DN9856_c0_g1_i1 len=467 path=[0:0-466]
GATGCGGGCCAATATGAATGTGAGATTACTAATGAATTGGGGACTAAAAA
TRINITY_DN9842_c0_g1_i1 len=208 path=[0:0-207]
AAGTAATTTTATATCACTTGTTACATCGCAATTCGTGAGTTAAACTTAAT
.
.
TRINITY_DN9897_c0_g1_i1 len=407 path=[0:0-406]
AACTTTATTAACTTGTTGTACATATTTATTAATGCAAATACATATAGAG  
TRINITY_DN9803_c0_g1_i1 len=795 path=[0:0-794]
AACTAAGACAAACTTCGCGGAGCAGTTAGAAAATATTACAAGAGATTTG
我想删除文件2中的两行(同一行和下一行),它们的模式与第一个文件的第一列字匹配

awk '{print $1}' file1 | sed '/here_i_want_to_insert_output_of_pipe/{N;d;}' file2


我会用流程替换这样做:

while read -r -d '' line; do
    sed -i "/^${line}/{N;d;}" file2
done < <(awk '{printf "%s\0", $1}' file1 | sed 's|[][\\/.*^$]|\\&|g')
读取-r-d“”行时;做
sed-i“/^${line}/{N;d;}”文件2

完成<我会用流程替换这样做:

while read -r -d '' line; do
    sed -i "/^${line}/{N;d;}" file2
done < <(awk '{printf "%s\0", $1}' file1 | sed 's|[][\\/.*^$]|\\&|g')
读取-r-d“”行时;做
sed-i“/^${line}/{N;d;}”文件2

完成<如果该字段在第一个字段中没有特殊字符,例如
/
[
\
或任何正则表达式特殊字符,那么您的想法实际上没有那么糟糕:

sed "$(cut -d' ' -f1 file1 | sed 's@.*@/&/{N;d}@')" file2
  • 剪切-d'-f1文件1
    -从文件1中提取第一个字段
  • | sed
    • *
      -替换任何内容,即文件1中的第一个字段
    • /&/{N;d}
      -
      &
      替换了我们要替换的整个内容。第一个字段也是如此。因此它变成了
      /{N;d}
  • 然后将其环绕在
    sed”文件2上
没有那么多已知的功能,您可以使用另一个字符作为
/regex/
的语法
\regex
,如
\!regex!
。下面我使用
~

 sed "$(cut -d' ' -f1 file1 | sed 's@.*@\\~&~{N;d}@')" file2
但是,如果您在第一个字段上有任何特殊字符,那么如果您不关心排序:您可以用一些神奇的分隔符(我在下面选择了
)替换file2中的两行作为单行,然后对其进行排序并对文件1进行排序,然后只将它们连接起来。
-v2
使
join
从第二个文件中输出不成对的行,即不匹配的行。之后,通过替换新行的魔法分隔符
,恢复新行:

join -v2 <(cut -d' ' -f1 file1 | sort) <(sed 'N;s/\n/!/' file2 | sort -k1) |
tr '!' '\n'

join-v2如果字段在第一个字段中没有特殊字符,比如
[
\
或任何正则表达式特殊字符,那么您的想法实际上并没有那么糟糕:

sed "$(cut -d' ' -f1 file1 | sed 's@.*@/&/{N;d}@')" file2
  • 剪切-d'-f1文件1
    -从文件1中提取第一个字段
  • | sed
    • *
      -替换任何内容,即文件1中的第一个字段
    • /&/{N;d}
      -
      &
      替换了我们要替换的整个内容。第一个字段也是如此。因此它变成了
      /{N;d}
  • 然后将其环绕在
    sed”文件2上
没有那么多已知的功能,您可以使用另一个字符作为
/regex/
的语法
\regex
,如
\!regex!
。下面我使用
~

 sed "$(cut -d' ' -f1 file1 | sed 's@.*@\\~&~{N;d}@')" file2
但是,如果您在第一个字段上有任何特殊字符,那么如果您不关心排序:您可以用一些神奇的分隔符(我在下面选择了
)替换file2中的两行作为单行,然后对其进行排序并对文件1进行排序,然后只将它们连接起来。
-v2
使
join
从第二个文件中输出不成对的行,即不匹配的行。之后,通过替换新行的魔法分隔符
,恢复新行:

join -v2 <(cut -d' ' -f1 file1 | sort) <(sed 'N;s/\n/!/' file2 | sort -k1) |
tr '!' '\n'

join-v2我会用一个awk做类似的事情,除非file1非常大:

awk 'NR==FNR{a[$1]++; next}counter{counter--}$1 in a{counter=2}!counter' <file1> <file2>
文件2:

TRINITY_DN9856_c0_g1_i1 len=467 path=[0:0-466]
GATGCGGGCCAATATGAATGTGAGATTACTAATGAATTGGGGACTAAAAA
TRINITY_DN9842_c0_g1_i1 len=208 path=[0:0-207]
AAGTAATTTTATATCACTTGTTACATCGCAATTCGTGAGTTAAACTTAAT
TRINITY_DN9897_c0_g1_i1 len=407 path=[0:0-406]
AACTTTATTAACTTGTTGTACATATTTATTAATGCAAATACATATAGAG  
hello
world
TRINITY_DN9803_c0_g1_i1 len=795 path=[0:0-794]
AACTAAGACAAACTTCGCGGAGCAGTTAGAAAATATTACAAGAGATTTG
输出:

TRINITY_DN9856_c0_g1_i1 len=467 path=[0:0-466]
GATGCGGGCCAATATGAATGTGAGATTACTAATGAATTGGGGACTAAAAA
TRINITY_DN9842_c0_g1_i1 len=208 path=[0:0-207]
AAGTAATTTTATATCACTTGTTACATCGCAATTCGTGAGTTAAACTTAAT
TRINITY_DN9897_c0_g1_i1 len=407 path=[0:0-406]
AACTTTATTAACTTGTTGTACATATTTATTAATGCAAATACATATAGAG  
TRINITY_DN9803_c0_g1_i1 len=795 path=[0:0-794]
AACTAAGACAAACTTCGCGGAGCAGTTAGAAAATATTACAAGAGATTTG

我会用一个awk做类似的事情,除非file1非常大:

awk 'NR==FNR{a[$1]++; next}counter{counter--}$1 in a{counter=2}!counter' <file1> <file2>
文件2:

TRINITY_DN9856_c0_g1_i1 len=467 path=[0:0-466]
GATGCGGGCCAATATGAATGTGAGATTACTAATGAATTGGGGACTAAAAA
TRINITY_DN9842_c0_g1_i1 len=208 path=[0:0-207]
AAGTAATTTTATATCACTTGTTACATCGCAATTCGTGAGTTAAACTTAAT
TRINITY_DN9897_c0_g1_i1 len=407 path=[0:0-406]
AACTTTATTAACTTGTTGTACATATTTATTAATGCAAATACATATAGAG  
hello
world
TRINITY_DN9803_c0_g1_i1 len=795 path=[0:0-794]
AACTAAGACAAACTTCGCGGAGCAGTTAGAAAATATTACAAGAGATTTG
输出:

TRINITY_DN9856_c0_g1_i1 len=467 path=[0:0-466]
GATGCGGGCCAATATGAATGTGAGATTACTAATGAATTGGGGACTAAAAA
TRINITY_DN9842_c0_g1_i1 len=208 path=[0:0-207]
AAGTAATTTTATATCACTTGTTACATCGCAATTCGTGAGTTAAACTTAAT
TRINITY_DN9897_c0_g1_i1 len=407 path=[0:0-406]
AACTTTATTAACTTGTTGTACATATTTATTAATGCAAATACATATAGAG  
TRINITY_DN9803_c0_g1_i1 len=795 path=[0:0-794]
AACTAAGACAAACTTCGCGGAGCAGTTAGAAAATATTACAAGAGATTTG

欢迎来到SO,很好,你已经展示了你尝试的代码。请用代码标签包装你的样本,因为它们不清楚。@RavinderSingh13我是一名生物学家,我不知道如何正确描述这个问题,谢谢你。我没有说解释,我只是要求用代码标签包装你的样本。只是想知道,你是否错过了
在TRINITY
前面?@kvantour我知道你是一名生物学家,我删除了>符号以使我的问题更一般化,这样我可以很快得到答案欢迎来到这里,很好,你展示了你尝试的代码。请用代码标签包装你的样本,因为它们不清楚。@RavinderSingh13我是一名生物学家,我不知道怎么做为了正确地描述这个问题,谢谢。我没有说明解释,我只是要求用代码标签包装您的样本。只是想知道,您是否错过了TRINITY前面的
?@kvantour我知道您是一名生物学家,我删除了>符号以使我的问题更一般化,这样我可以快速得到答案ed“$(剪切-d'-f1文件1 | sed”s@.*@/&/{N;d}@')“文件2这个解决方案对我来说已经足够了。谢谢KamilCuk。我非常高兴能从开发人员那里得到帮助。再次感谢您插入“$(cut-d'-f1文件1|sed”s@.*@/&/{N;d}@')”file2这个解决方案对我来说已经足够了。谢谢你KamilCuk。我非常高兴能从一个开发者那里得到帮助。再次非常感谢你