Answers.Body: <p>One way using <a href="/questions/tagged/sed" class="post-tag" title="show questions tagged &#39;sed&#39;" aria-label="show questions tagged &#39;sed&#39;" rel="tag" aria-labelledby="sed-container">sed</a>:</p>
  <pre><code>sed -n '/^&gt;/s/.*\[\([^]]*\)\]$/\1/p' input.fa
  </code></pre>
  <p>Results:</p>
  <pre><code>C.sp. balc.
  D.r.
  E.l.
  </code></pre>
  <p>Explanation:</p>
  <ul>
  <li>Turn off automatic printing of the pattern space using <code>-n</code></li>
  <li>Address lines starting with a header using <code>/^&gt;/</code></li>
  <li>Perform a substitution using a capture group to select everything between the last set of brackets on these lines, with <code>s/.*\[\([^]]*\)\]$/\1/</code></li>
  <li>Print the pattern space with <code>p</code></li>
  </ul>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T11:34:03.873Z
Answers.Text: You could probably simplify your sed to `sed -n '/^>/{s/.*\[//; s/]//p}' file`.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-11T23:47:02.597Z
Answers.Text: The `/^>/{` doesn't appear to be necessary.
Answers.UserDisplayName: Ed Morton
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-12T15:49:15.667Z
Answers.LastActivityDate: 2022-12-12T15:56:15.797Z
Answers.LastEditDate: 2022-12-12T15:56:15.797Z
Answers.UserDisplayName: Steve
Answers.Body: <p>With GNU <code>grep</code> (the default on Linux):</p>
  <pre><code>$ grep -oP '.*\[\K[^]]+' file
  C.sp. balc.
  D.r.
  E.l.
  </code></pre>
  <p>The <code>-o</code> means &quot;print only the matched portion of the line&quot; and <code>-P</code> enables Perl Compatible Regular Expressions which give us <code>\K</code> for &quot;ignore everything matched up to this point&quot;. So we then look for the longest possible string ending in a <code>[</code> and discard it (<code>.*\[\K</code>), and then look for the longest possible stretch of non-<code>]</code> characters after that.</p>
  <p>For very large files, you can speed things up a little by focusing only on the header lines:</p>
  <pre><code>grep -oP '^&gt;.*\[\K[^]]+' file
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T11:32:04.507Z
Answers.LastActivityDate: 2022-12-13T11:32:04.507Z
Answers.UserDisplayName: terdon
Answers.Body: <p>For OSX, I don't have a <code>-P</code> option (Perl pattern matching) so the best I can do is finish the one-liner by piping into <code>perl</code></p>
  <pre><code>grep -o '\[.*\]\[[^]]*' input.fa | perl -p -e 's/[][]/ /g'
  </code></pre>
  <p>The <code>-o</code> makes <code>grep</code> match the substring, rather than the entire line.</p>
  <p>With GNU <code>grep</code> (the default on Linux) and the <code>-P</code> option, it's a single line of grep where <code>\K</code> or <code>(?=pattern)</code>, <code>(?&lt;=pattern)</code> are used for non-capture characters and these are placed around the <code>[</code></p>
  <pre><code>grep -oP '(?&lt;=\[).*(?=\]).*(?&lt;=\[)[^]]*' input.fa
  </code></pre>
  <p>The <code>?&lt;=</code> is a <a href="https://www.regextutorial.org/positive-and-negative-lookbehind-assertions.php" rel="nofollow noreferrer">&quot;positive lookbehind&quot;</a> and the <code>?=</code> is a <a href="https://www.regextutorial.org/positive-and-negative-lookahead-assertions.php" rel="nofollow noreferrer">&quot;positive lookahead&quot;</a>.</p>
  <p>It's a lot easier to use a <code>perl</code> one-liner.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-12T15:43:25.613Z
Answers.Text: You could also pipe to sed, and skip the Perl dependency: `grep -o '\[[^]]*\]$' input.fa | sed 's/[][]//g'`
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T11:13:10.183Z
Answers.Text: @Steve what benefit would that give? You just added sed as a dependency instead. Both sed and perl are installed by default on the vast majority of systems, so unless you are using AIX or a very limited embedded system, perl is just as valid as sed.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T15:10:45.350Z
Answers.Text: @terdon I agree, but nearly all systems with grep will have sed.
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T16:03:41.897Z
Answers.Text: @Steve yes, exactly like `perl`. Unless people are trying to do bioinformatics on toasters or something, I really don't see any point in using sed instead of perl. They are both very powerful, standard, ancient commands that have a long history in the *nix world in general and in bioinformatics in particular. The only full system (as opposed to embedded system) I know of that doesn't install perl by default is AIX and that isn't likely to be used for bioinformatics.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T18:38:11.717Z
Answers.Text: Perl can easily be downloaded @Steve ;), "Dockerised", or "conda-ised". Not many Linux OS have removed Perl, `FreeBSD` is one. Most of us work with `Ubuntu`, `Debian` or `Darwin`. I think even Alpine Linux has Perl.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T02:12:07.800Z
Answers.Text: @terdon Well, Perl is a sed-killer. For simple substitutions like the above, PCRE are not needed. You can use Perl if you want to, but you _could_ also use sed and not need to escape the brackets.
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T02:15:57.840Z
Answers.Text: @M__ Alpine does not come with Perl out of the box
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T10:54:57.900Z
Answers.Text: @Steve well yes, but Alpine is mostly for embedded systems, right? Not sure what you mean about escaping, neither tool requires you to escape the brackets. And sure, of course you can use `sed`. I just don't see any benefit in using one external tool over another here. Nothing wrong with using sed, but nothing wrong with using perl either. Granted, if I bring out perl, I would probably do the whole thing in perl and remove the grep, but still.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T13:00:38.653Z
Answers.Text: @Steve yes technically Alpine Linux holds `sed` and `grep` but via `Busybox` and its `grep` is basic without `-P`. I installed `perl` on Alpine it took a few seconds  maximum. However, the reason is the container is 7.5 MG and Alpine `Perl` is 55MB. The key to the question is `GNU` grep.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T14:07:40.493Z
Answers.Text: @terdon You're right, neither tool requires the brackets to be escaped but `'s/[[]]/ /g'` should be `'s/[][]/ /g` I think.
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T14:35:55.677Z
Answers.Text: @Steve eeeek! You're quite right, thanks!
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-15T02:08:19.470Z
Answers.Text: @Steve here's an article specially written for you ;) https://stackoverflow.blog/2022/07/06/why-perl-is-still-relevant-in-2022/
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-15T03:24:50.113Z
Answers.Text: Thanks @M__ - I hadn't even heard of Perl 7 until now. But then I haven't really touched Perl for nearly a decade now. I just hope you're not confusing me for someone who dislikes Perl - that's certainly not the case. It's just that it's not needed here in my opinion. The Perl dependency also makes pipelining the solution tricky using the standard (i.e. non-mulled) quay.io biocontainers which provide the busybox suite. But that's not likely even a concern here..
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-15T17:34:10.157Z
Answers.Text: @Steve "not confusing me for someone who dislikes Perl " ... just checking ;) Fun as this is the last 3 comments at least need to be deleted, probably more
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-15T17:41:34.733Z
Answers.Text: @terdon Alpine is a "freak" Linux OS, just for Docker containers. I should have checked my information before introducing it here :)
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-12T15:08:05.770Z
Answers.LastActivityDate: 2022-12-14T14:36:21.067Z
Answers.LastEditDate: 2022-12-14T14:36:21.067Z
Answers.UserDisplayName: M__
Answers.Body: <p>Some of the solutions suggested above utilize GNU <code>grep.</code> If you are a Mac user, you can easily install GNU version of the commands into your Mac. You can do this by installing the GNU Command Line Tools. The easiest way is to use Homebrew, then <code>brew install coreutils.</code></p>
  <p>The default commands will still be MacOS version (unless you intentionally set otherwise), but when you want to use GNU version, you could just add a <code>g</code> before the command. For example, <code>sort</code> vs <code>gsort</code>, <code>grep</code> vs <code>ggrep</code>. You can also check manual of the command the same way, e.g. <code>man gsort</code>. Trust me this will make your life easier as a Mac user.</p>
  <p>Also, in recent years default MacOS Terminal shell is <code>zsh.</code> If you desire you can switch it back to <code>bash</code>.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-22T03:11:27.687Z
Answers.Text: Thanks @Supertech perfect
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-22T01:34:15.903Z
Answers.LastActivityDate: 2022-12-22T01:34:15.903Z
Answers.UserDisplayName: Supertech
Body: <p>I would like to grep everything inside the second square bracket of a file:</p>
  <pre><code>&gt;AB1311658.1 unnamed protein product [C.sp. balc.]
  
  &gt;evm.model.pilon.8 [actin][D.r.]
  
  &gt;NP_0232343.1 [fucose mutarotase] [E.l.]
  </code></pre>
  <p>Obtaining:</p>
  <pre><code>C.sp. balc.
  
  D.r.
  
  E.l.
  </code></pre>
  <p>How can I solve it?</p>
  <p>Marco</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-12-12T14:34:07.007Z
Comments.Text: Is that _everything_ you have in the file? No other lines? And what operating system are you using?
Comments.UserDisplayName: terdon
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-12-15T02:16:37.800Z
Comments.Text: You can easily install GNU version of the commands into your Mac. Install the GNU Command Line Tools. You can do this using Homebrew, then
  brew install coreutils. Default will be MacOS version (unless you intentionally set otherwise), but when you want to use GNU version, just add a "g" before the command. For example, "sort" vs "gsort"; "grep" vs "ggrep". It will make your life easier as a Mac user.
Comments.UserDisplayName: Supertech
Tags: <fasta><genome><grep>
Title: Grep peculiar pattern inside a file
ThreadText: # Grep peculiar pattern inside a file
  
  (Asked by: username_0 on 2022-12-12)
  
  I would like to grep everything inside the second square bracket of a file:
  
  ```
  >AB1311658.1 unnamed protein product [C.sp. balc.]
  
  >evm.model.pilon.8 [actin][D.r.]
  
  >NP_0232343.1 [fucose mutarotase] [E.l.]
  
  ```
  
  Obtaining:
  
  ```
  C.sp. balc.
  
  D.r.
  
  E.l.
  
  ```
  
  How can I solve it?
  
  username_0
  
  **Tags:** fasta, genome, grep
  
  > **Comments:**
  > **username_1**: Is that _everything_ you have in the file? No other lines? And what operating system are you using?  
  > **username_2**: You can easily install GNU version of the commands into your Mac. Install the GNU Command Line Tools. You can do this using Homebrew, then brew install coreutils. Default will be MacOS version (unless you intentionally set otherwise), but when you want to use GNU version, just add a "g" before the command. For example, "sort" vs "gsort"; "grep" vs "ggrep". It will make your life easier as a Mac user.  
  
  ---
  
  ## 4 answers
  
  ### Answer by username_3 on 2022-12-12. Score: 4
  
  One way using [sed](/questions/tagged/sed "show questions tagged 'sed'"):
  
  ```
  sed -n '/^>/s/.*\[\([^]]*\)\]$/\1/p' input.fa
  
  ```
  
  Results:
  
  ```
  C.sp. balc.
  D.r.
  E.l.
  
  ```
  
  Explanation:
  
  * Turn off automatic printing of the pattern space using `-n`
  * Address lines starting with a header using `/^>/`
  * Perform a substitution using a capture group to select everything between the last set of brackets on these lines, with `s/.*\[\([^]]*\)\]$/\1/`
  * Print the pattern space with `p`
  
  > **Comments:**
  > **username_1**: You could probably simplify your sed to `sed -n '/^>/{s/.*\[//; s/]//p}' file`.  
  > **username_4**: The `/^>/{` doesn't appear to be necessary.  
  
  ---
  
  ### Answer by username_1 on 2022-12-13. Score: 3
  
  With GNU `grep` (the default on Linux):
  
  ```
  $ grep -oP '.*\[\K[^]]+' file
  C.sp. balc.
  D.r.
  E.l.
  
  ```
  
  The `-o` means "print only the matched portion of the line" and `-P` enables Perl Compatible Regular Expressions which give us `\K` for "ignore everything matched up to this point". So we then look for the longest possible string ending in a `[` and discard it (`.*\[\K`), and then look for the longest possible stretch of non-`]` characters after that.
  
  For very large files, you can speed things up a little by focusing only on the header lines:
  
  ```
  grep -oP '^>.*\[\K[^]]+' file
  
  ```
  
  
  ---
  
  ### Answer by username_5 on 2022-12-12. Score: 2
  
  For OSX, I don't have a `-P` option (Perl pattern matching) so the best I can do is finish the one-liner by piping into `perl`
  
  ```
  grep -o '\[.*\]\[[^]]*' input.fa | perl -p -e 's/[][]/ /g'
  
  ```
  
  The `-o` makes `grep` match the substring, rather than the entire line.
  
  With GNU `grep` (the default on Linux) and the `-P` option, it's a single line of grep where `\K` or `(?=pattern)`, `(?<=pattern)` are used for non-capture characters and these are placed around the `[`
  
  ```
  grep -oP '(?<=\[).*(?=\]).*(?<=\[)[^]]*' input.fa
  
  ```
  
  The `?<=` is a ["positive lookbehind"](https://www.regextutorial.org/positive-and-negative-lookbehind-assertions.php) and the `?=` is a ["positive lookahead"](https://www.regextutorial.org/positive-and-negative-lookahead-assertions.php).
  
  It's a lot easier to use a `perl` one-liner.
  
  > **Comments:**
  > **username_3**: You could also pipe to sed, and skip the Perl dependency: `grep -o '\[[^]]*\]$' input.fa | sed 's/[][]//g'`  
  > **username_1**: @username_3 what benefit would that give? You just added sed as a dependency instead. Both sed and perl are installed by default on the vast majority of systems, so unless you are using AIX or a very limited embedded system, perl is just as valid as sed.  
  > **username_3**: @username_1 I agree, but nearly all systems with grep will have sed.  
  > **username_1**: @username_3 yes, exactly like `perl`. Unless people are trying to do bioinformatics on toasters or something, I really don't see any point in using sed instead of perl. They are both very powerful, standard, ancient commands that have a long history in the *nix world in general and in bioinformatics in particular. The only full system (as opposed to embedded system) I know of that doesn't install perl by default is AIX and that isn't likely to be used for bioinformatics.  
  > **username_5**: Perl can easily be downloaded @username_3 ;), "Dockerised", or "conda-ised". Not many Linux OS have removed Perl, `FreeBSD` is one. Most of us work with `Ubuntu`, `Debian` or `Darwin`. I think even Alpine Linux has Perl.  
  > **username_3**: @username_1 Well, Perl is a sed-killer. For simple substitutions like the above, PCRE are not needed. You can use Perl if you want to, but you _could_ also use sed and not need to escape the brackets.  
  > **username_3**: @username_5 Alpine does not come with Perl out of the box  
  > **username_1**: @username_3 well yes, but Alpine is mostly for embedded systems, right? Not sure what you mean about escaping, neither tool requires you to escape the brackets. And sure, of course you can use `sed`. I just don't see any benefit in using one external tool over another here. Nothing wrong with using sed, but nothing wrong with using perl either. Granted, if I bring out perl, I would probably do the whole thing in perl and remove the grep, but still.  
  > **username_5**: @username_3 yes technically Alpine Linux holds `sed` and `grep` but via `Busybox` and its `grep` is basic without `-P`. I installed `perl` on Alpine it took a few seconds  maximum. However, the reason is the container is 7.5 MG and Alpine `Perl` is 55MB. The key to the question is `GNU` grep.  
  > **username_3**: @username_1 You're right, neither tool requires the brackets to be escaped but `'s/[[]]/ /g'` should be `'s/[][]/ /g` I think.  
  > **username_1**: @username_3 eeeek! You're quite right, thanks!  
  > **username_5**: @username_3 here's an article specially written for you ;) https://stackoverflow.blog/2022/07/06/why-perl-is-still-relevant-in-2022/  
  > **username_3**: Thanks @username_5 - I hadn't even heard of Perl 7 until now. But then I haven't really touched Perl for nearly a decade now. I just hope you're not confusing me for someone who dislikes Perl - that's certainly not the case. It's just that it's not needed here in my opinion. The Perl dependency also makes pipelining the solution tricky using the standard (i.e. non-mulled) quay.io biocontainers which provide the busybox suite. But that's not likely even a concern here..  
  > **username_5**: @username_3 "not confusing me for someone who dislikes Perl " ... just checking ;) Fun as this is the last 3 comments at least need to be deleted, probably more  
  > **username_5**: @username_1 Alpine is a "freak" Linux OS, just for Docker containers. I should have checked my information before introducing it here :)  
  
  ---
  
  ### Answer by username_2 on 2022-12-22. Score: 1
  
  Some of the solutions suggested above utilize GNU `grep.` If you are a Mac user, you can easily install GNU version of the commands into your Mac. You can do this by installing the GNU Command Line Tools. The easiest way is to use Homebrew, then `brew install coreutils.`
  
  The default commands will still be MacOS version (unless you intentionally set otherwise), but when you want to use GNU version, you could just add a `g` before the command. For example, `sort` vs `gsort`, `grep` vs `ggrep`. You can also check manual of the command the same way, e.g. `man gsort`. Trust me this will make your life easier as a Mac user.
  
  Also, in recent years default MacOS Terminal shell is `zsh.` If you desire you can switch it back to `bash`.
  
  > **Comments:**
  > **username_5**: Thanks @username_2 perfect  
  
  ---
  
  