Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-08T23:45:15.177Z
Answers.Text: 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`.
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-08T22:59:45.967Z
Answers.LastActivityDate: 2023-03-08T23:55:16.893Z
Answers.LastEditDate: 2023-03-08T23:55:16.893Z
Answers.UserDisplayName: jared_mamrot
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-09T09:33:15.793Z
Answers.Text: Thanx guys. All of the codes above work well for me. I appreciated it.
Answers.UserDisplayName: Amal
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-08T23:15:08.697Z
Answers.LastActivityDate: 2023-03-08T23:26:20.597Z
Answers.LastEditDate: 2023-03-08T23:26:20.597Z
Answers.UserDisplayName: Steve
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-08T15:05:02.553Z
Answers.LastActivityDate: 2023-03-08T16:45:35.017Z
Answers.LastEditDate: 2023-03-08T16:45:35.017Z
Answers.UserDisplayName: Ram RS
Body: <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>
  
Tags: <proteins><protein-structure><linux><awk>
Title: How to retrieve sequences from a txt file by protein names from other txt file?
ThreadText: # 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](/questions/tagged/awk "show questions tagged '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
  ```
  
  ```
  
  
  ---
  
  