括弧外の内容を削除する方法

括弧外の内容を削除する方法

以下は、「\ t」で区切られた2つの列を含む私のファイルです。

a    HK97 family prohead protease [Lomovskayavirus C31]
b    major capsid protein [Lomovskayavirus C31]
c    gp12 [Lomovskayavirus C31]
d    gp19 [Lomovskayavirus C31]
 

sedがこのようなファイルを取得できることを願っています。

a    Lomovskayavirus C31
b    Lomovskayavirus C31
c    Lomovskayavirus C31
d    Lomovskayavirus C31

コマンドを試しましたがうまくsed 's/.*[\(.*\)].*/\1/'いかないようです。それでは、何を変えるべきですか?ありがとうございます。

答え1

すべてのUnixシステムのすべてのシェルでawkを使用してください。

$ awk -F '[][\t]' -v OFS='\t' '{print $1, $3}' file
a       Lomovskayavirus C31
b       Lomovskayavirus C31
c       Lomovskayavirus C31
d       Lomovskayavirus C31

答え2

[and]は特別な意味(後で必要になる一致する文字セット)を持つため、エスケープする必要があり、次のような結果が得られます。

sed 's/.*\[\(.*\)\].*/\1/'

しかし、これを行うと、最初の列も削除されます。

sed 's/[ [:alnum:]]*\[\(.*\)\].*/\1/'

したがって、最初の部分はすべての英数字とスペースをキャプチャしますが、タブ文字はキャプチャしないため、タブ文字の後のすべての内容が削除されます。

答え3

使用幸せ(以前のPerl_6)

perl6 -ne 'given .split(/\s+/, 2) { put (.[0], .[1].match: / <?after "[" > .+ <?before "]" > /).join("\t") };'  

または

raku -ne 'given .split(/\s+/, 2) { put (.[0], .[1].comb: / "[" <(.+)> "]" /.[0]).join("\t") };'  

Perl言語ファミリーは、厳しい正規表現の問題を解決する良い方法です。上記の2つの戦略は混在して一致することができます。つまり、キャプチャタグcombだけでなく、プレビュー/反転アサーションも使用できますmatch

上記の最初の例では、各行にスペースがありsplitますが、2つの部分\s+にのみ分割されています。次に、最初の要素を配置し、22番目の要素からmatchパターンを検索します<?after "[" > .+ <?before "]" >。正規表現原子は <?after … >ラクの肯定的な予測アサーションです。<?before … >正規表現原子はラクの肯定的な予測アサーションです。これらのアサーションは幅が0なので、キャプチャマーカーは必要なく、一致変数($/or)を直接出力できます。$<>

2番目の例では、split各行を\s+余白に配置し、2つの2フラグメントに再び分割します。最初の要素を再配置し、2番目の要素を繰り返して、で囲まれた1つ以上の文字をcomb見つけます。.+Rakuの...captureフラグは、出力から括弧を除外するために使用されます(2番目の列で最初のedの発生を返すために最後にインデックスを追加します)。[]<()>.[0]comb

入力例:

a    HK97 family prohead protease [Lomovskayavirus C31]
b    major capsid protein [Lomovskayavirus C31]
c    gp12 [Lomovskayavirus C31]
d    gp19 [Lomovskayavirus C31]

出力例(上記の2つの例):

a   Lomovskayavirus C31
b   Lomovskayavirus C31
c   Lomovskayavirus C31
d   Lomovskayavirus C31

とにかく最初の列を削除するには、上記のコードを次のように単純化できます。

raku -ne 'put m/ <?after \[>  .+  <?before \]> /;'   

または

raku -ne 'put .comb(/ \[  <(.+)>  \] /).[0];'    

https://raku.org

答え4

使用sed

$ sed -E 's/( +)[^[]*\[([^]]*).*/\1\2/' input_file
a    Lomovskayavirus C31
b    Lomovskayavirus C31
c    Lomovskayavirus C31
d    Lomovskayavirus C31

関連情報