<p>If your file structure is consistent, one potential solution is to use GNU grep:</p>
<pre><code>grep -A4 --no-group-separator -Fwf header.txt pdb.txt
</code></pre>
<p>This works with your example data and should be relatively fast on your 'real' data, due to <code>-Fw</code> ('fixed' i.e. not regex, and only match whole words) but it requires GNU grep for the <code>--no-group-separator</code> option (i.e. not BSD grep).</p>

CC BY-SA 4.0
2023-03-08T23:45:15.177Z
The only issue here is that it tests `$1 in a` for each line of input (in _pdb.txt_). It might not do the right thing if the list of headers contains a protein name called 'M', for example. It's exactly the same as: `FNR==NR { a[$1]; next } $1 in a { x = FNR+4 } FNR <= x`.
Steve
CC BY-SA 4.0
2023-03-08T22:59:45.967Z
2023-03-08T23:55:16.893Z
2023-03-08T23:55:16.893Z
jared_mamrot
<p>One way using <a href="/questions/tagged/awk" class="post-tag" title="show questions tagged &#39;awk&#39;" aria-label="show questions tagged &#39;awk&#39;" rel="tag" aria-labelledby="tag-awk-tooltip-container">awk</a>:</p>
<pre><code>awk 'FNR==NR { a[$1]; next } FNR%5==1 { f = ($1 in a) ? 1 : 0 }f' header.txt pdb.txt 
</code></pre>
<p>This adds each of the protein names in <em>header.txt</em> to an array. By adding the first field (<code>$1</code>), rather than the complete record (<code>$0</code>) to the array, we can ensure that we strip off any lagging whitespace which can sometimes cause problems depending on how the list of protein names was created. Next, we can check whether the record number (i.e. line number) of the second input file is a multiple of 5 with remainder 1. This condition returns true for the first line of each record in <em>pdb.txt</em>. We can then use a ternary operator to set a flag variable to one if the first field of the current line (i.e., the protein name) is present in the a array, <em>or</em> to zero to indicate that the current record is not one of the records in the array. The <code>f</code> by itself is just shorthand for <code>f != 0 { print }</code>, which prints the current line when the flag is non-zero.</p>

CC BY-SA 4.0
2023-03-09T09:33:15.793Z
Thanx guys. All of the codes above work well for me. I appreciated it.
Amal
CC BY-SA 4.0
2023-03-08T23:15:08.697Z
2023-03-08T23:26:20.597Z
2023-03-08T23:26:20.597Z
Steve
<p>I'm assuming that your second file is tab-delimited and has no commas. The easiest way to do this would be to transpose each record in your second file to a single line and then grep, then transform the result again:</p>
<pre><code>grep -Ff header.txt &lt;(paste -d, - - - - - &lt; pdb.txt) | tr &quot;,&quot; &quot;\n&quot;
</code></pre>
<p>I just tested and it works:</p>
<pre><code>➜ cat pdb.txt
4LGTD
247
M       S       E       K       L       Q       K       V       L       A       R
.       .       E       E       H       H       H       H       H       H       H

1XXIJ
334
M       R       W       Y       P       W       L       R       P       D       F
.       .       .       .       T       T       H       H       H       H       H

6U02G
116
E       V       Q       L       V       E       S       G       G       G       L
.       .       E       E       E       E       E       .       .       E       E

1P0EA
363
R       P       R       F       S       F       S       I       A       A       R
.       .       S       E       E       E       E       E       E       E       E

1H9HI
30
G       C       P       R       I       L       I       R       C       K       Q
.       E       E       .       .       .       .       B       S       S

➜ cat header.txt
1XXIJ
1P0EA
1H9HI

➜ grep -Ff header.txt &lt;(paste -d, - - - - - &lt; pdb.txt) | tr &quot;,&quot; &quot;\n&quot;
1XXIJ
334
M       R       W       Y       P       W       L       R       P       D       F
.       .       .       .       T       T       H       H       H       H       H

1P0EA
363
R       P       R       F       S       F       S       I       A       A       R
.       .       S       E       E       E       E       E       E       E       E

1H9HI
30
G       C       P       R       I       L       I       R       C       K       Q
.       E       E       .       .       .       .       B       S       S
<span class="math-container">```</span>
</code></pre>

CC BY-SA 4.0
2023-03-08T15:05:02.553Z
2023-03-08T16:45:35.017Z
2023-03-08T16:45:35.017Z
Ram RS
<p>My problem is that I want to retrieve the sequences line + secondary structure line that match the protein names from the <code>header.txt</code> file:</p>
<p>The text file(<code>header.txt</code>) contains the protein names that look like this:</p>
<pre><code>1XXIJ
1P0EA
1H9HI

</code></pre>
<p>And the other file(<code>pdb.txt</code>) structured like this:</p>
<p>Line 1:the protein name</p>
<p>Line 2: protein length</p>
<p>Line 3: amino acid sequence</p>
<p>Line 4: secondary structure</p>
<p>Line 5: empty</p>
<pre><code>4LGTD
247
M       S       E       K       L       Q       K       V       L       A       R       
.       .       E       E       H       H       H       H       H       H       H       

1XXIJ
334
M       R       W       Y       P       W       L       R       P       D       F       
.       .       .       .       T       T       H       H       H       H       H       

6U02G
116
E       V       Q       L       V       E       S       G       G       G       L       
.       .       E       E       E       E       E       .       .       E       E       

1P0EA
363
R       P       R       F       S       F       S       I       A       A       R       
.       .       S       E       E       E       E       E       E       E       E  
 
1H9HI
30
G       C       P       R       I       L       I       R       C       K       Q       
.       E       E       .       .       .       .       B       S       S

</code></pre>
<p>So my expected output is:</p>
<pre><code>1XXIJ
334
M       R       W       Y       P       W       L       R       P       D       F       
.       .       .       .       T       T       H       H       H       H       H       

1P0EA
363
R       P       R       F       S       F       S       I       A       A       R       
.       .       S       E       E       E       E       E       E       E       E  
 
1H9HI
30
G       C       P       R       I       L       I       R       C       K       Q       
.       E       E       .       .       .       .       B       S       S

</code></pre>
<p>Do you guys have any suggestions for me by awk or any(Linux)code? Please let me know if you require additional information. Cheers!</p>

<proteins><protein-structure><linux><awk>
How to retrieve sequences from a txt file by protein names from other txt file?
# How to retrieve sequences from a txt file by protein names from other txt file?

(Asked by: username_0 on 2023-03-08)

My problem is that I want to retrieve the sequences line + secondary structure line that match the protein names from the header.txt file:
The text file(header.txt) contains the protein names that look like this:
1XXIJ
1P0EA
1H9HI


And the other file(pdb.txt) structured like this:
Line 1:the protein name
Line 2: protein length
Line 3: amino acid sequence
Line 4: secondary structure
Line 5: empty
4LGTD
247
M       S       E       K       L       Q       K       V       L       A       R       
.       .       E       E       H       H       H       H       H       H       H       

1XXIJ
334
M       R       W       Y       P       W       L       R       P       D       F       
.       .       .       .       T       T       H       H       H       H       H       

6U02G
116
E       V       Q       L       V       E       S       G       G       G       L       
.       .       E       E       E       E       E       .       .       E       E       

1P0EA
363
R       P       R       F       S       F       S       I       A       A       R       
.       .       S       E       E       E       E       E       E       E       E  
 
1H9HI
30
G       C       P       R       I       L       I       R       C       K       Q       
.       E       E       .       .       .       .       B       S       S


So my expected output is:
1XXIJ
334
M       R       W       Y       P       W       L       R       P       D       F       
.       .       .       .       T       T       H       H       H       H       H       

1P0EA
363
R       P       R       F       S       F       S       I       A       A       R       
.       .       S       E       E       E       E       E       E       E       E  
 
1H9HI
30
G       C       P       R       I       L       I       R       C       K       Q       
.       E       E       .       .       .       .       B       S       S


Do you guys have any suggestions for me by awk or any(Linux)code? Please let me know if you require additional information. Cheers!

**Tags:** proteins, protein-structure, linux, awk

---

## 3 answers

### Answer by username_1 on 2023-03-08. Score: 2 | Accepted answer

If your file structure is consistent, one potential solution is to use GNU grep:
grep -A4 --no-group-separator -Fwf header.txt pdb.txt

This works with your example data and should be relatively fast on your 'real' data, due to -Fw ('fixed' i.e. not regex, and only match whole words) but it requires GNU grep for the --no-group-separator option (i.e. not BSD grep).

> **Comments:**
> **username_2**: The only issue here is that it tests `$1 in a` for each line of input (in _pdb.txt_). It might not do the right thing if the list of headers contains a protein name called 'M', for example. It's exactly the same as: `FNR==NR { a[$1]; next } $1 in a { x = FNR+4 } FNR <= x`.  

---

### Answer by username_2 on 2023-03-08. Score: 2

One way using awk:
awk 'FNR==NR { a[$1]; next } FNR%5==1 { f = ($1 in a) ? 1 : 0 }f' header.txt pdb.txt 

This adds each of the protein names in header.txt to an array. By adding the first field ($1), rather than the complete record ($0) to the array, we can ensure that we strip off any lagging whitespace which can sometimes cause problems depending on how the list of protein names was created. Next, we can check whether the record number (i.e. line number) of the second input file is a multiple of 5 with remainder 1. This condition returns true for the first line of each record in pdb.txt. We can then use a ternary operator to set a flag variable to one if the first field of the current line (i.e., the protein name) is present in the a array, or to zero to indicate that the current record is not one of the records in the array. The f by itself is just shorthand for f != 0 { print }, which prints the current line when the flag is non-zero.

> **Comments:**
> **username_0**: Thanx guys. All of the codes above work well for me. I appreciated it.  

---

### Answer by username_3 on 2023-03-08. Score: 2

I'm assuming that your second file is tab-delimited and has no commas. The easiest way to do this would be to transpose each record in your second file to a single line and then grep, then transform the result again:
grep -Ff header.txt <(paste -d, - - - - - < pdb.txt) | tr "," "\n"

I just tested and it works:
➜ cat pdb.txt
4LGTD
247
M       S       E       K       L       Q       K       V       L       A       R
.       .       E       E       H       H       H       H       H       H       H

1XXIJ
334
M       R       W       Y       P       W       L       R       P       D       F
.       .       .       .       T       T       H       H       H       H       H

6U02G
116
E       V       Q       L       V       E       S       G       G       G       L
.       .       E       E       E       E       E       .       .       E       E

1P0EA
363
R       P       R       F       S       F       S       I       A       A       R
.       .       S       E       E       E       E       E       E       E       E

1H9HI
30
G       C       P       R       I       L       I       R       C       K       Q
.       E       E       .       .       .       .       B       S       S

➜ cat header.txt
1XXIJ
1P0EA
1H9HI

➜ grep -Ff header.txt <(paste -d, - - - - - < pdb.txt) | tr "," "\n"
1XXIJ
334
M       R       W       Y       P       W       L       R       P       D       F
.       .       .       .       T       T       H       H       H       H       H

1P0EA
363
R       P       R       F       S       F       S       I       A       A       R
.       .       S       E       E       E       E       E       E       E       E

1H9HI
30
G       C       P       R       I       L       I       R       C       K       Q
.       E       E       .       .       .       .       B       S       S
```


---

