特定の列に文字列の特定の部分のみを保持する

特定の列に文字列の特定の部分のみを保持する

次のファイルがあります。

id  target_id                               length  eff_length
1   intron_FBgn0000721:20_FBgn0000721:18    1136    243.944268
1   intron_FBgn0000721:19_FBgn0000721:18    1122    240.237419
2   intron_FBgn0264373:2_FBgn0264373:3      56      0
3   intron_FBgn0027570:4_FBgn0027570:3      54      0

2番目の列では、target_id最初の列と2番目の列の間の文字列だけを保持したいと思いますFBgnXXXX(常にそうではなく、時には別の名前もあります)。したがって、新しい出力ファイルの列2の値はより単純になりますが、ファイルの残りの部分は同じままです。intron_:

sedコマンドを使ってみましたが、不要な部分を削除する方法がわかりません。

答え1

使用sedcolumn:

$ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/' file | column -t
id  target_id    length  eff_length
1   FBgn0000721  1136    243.944268
1   FBgn0000721  1122    240.237419
2   FBgn0264373  56      0

ここで重要な部分は交換コマンドです。

s/ intron_([^:]*):\S*/ \1/

最初のコロンの後ろintron_と前のすべてを見つけてintron_変数に保存します1[^[:space:]]*コロンからフィールドの終わりまでのすべての項目と一致します。これらはすべて変数に含まれるテキストに置き換えられます1

awkタブ区切りの出力と一緒に使用:

$ awk -v "OFS=\t" '{$2=$2;sub(/intron_/, "", $2); sub(/:.*/, "", $2); print}' file
id      target_id       length  eff_length
1       FBgn0000721     1136    243.944268
1       FBgn0000721     1122    240.237419
2       FBgn0264373     56      0

説明する:

  • -v "OFS=\t"

    これにより、出力フィールド区切り文字がタブに設定されます。これは列を並べ替えるのに役立ちますが、必ずしもcolumn必要ではありません。

  • $2=$2

    行が印刷されると、awk行で何かを変更しない限り、新しく指定された出力フィールド区切り文字に変更されません。 2番目のフィールドを2番目のフィールドに割り当てるだけで、出力にタブ文字があることを確認できます。

  • sub(/intron_/, "", $2)

    これはintron_2番目のフィールドから削除されます。

  • sub(/:.*/, "", $2)

    これにより、2番目のフィールドの最初のコロンの後のすべてのエントリが削除されます。

  • print

    これにより、新しい行が印刷されます。

awkカスタム列形式で使用

これは上記と似ていますが、printf必要に応じて列の幅と並べ替えをカスタマイズできるようにフォーマットを使用します。

$ awk  '{sub(/intron_/, "", $2); sub(/:.*/, "", $2); printf "%-3s %-12s %8s %3s\n",$1,$2,$3,$4}' file
id  target_id      length eff_length
1   FBgn0000721      1136 243.944268
1   FBgn0000721      1122 240.237419
2   FBgn0264373        56   0

ここのステートメントは、printf "%-3s %-12s %8s %3s\n",$1,$2,$3,$4一般的なスタイルで列の幅と並べ替えを選択しますprintf

タブ区切りを使用しsedてコンマ区切りに変換します。

$ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/; s/[[:space:]][[:space:]]*/,/g' file 
id,target_id,length,eff_length
1,FBgn0000721,1136,243.944268
1,FBgn0000721,1122,240.237419
2,FBgn0264373,56,0

答え2

あなたはそれを使用することができますperl

$ perl -anle '
    BEGIN {$" = "\t"}
    print "@{[@F]}" and next if $. == 1;
    $F[1] = $1 if /_([^:]*):/;
    print "@{[@F]}";
' file
id  target_id   length  eff_length
1   FBgn0000721 1136    243.944268
1   FBgn0000721 1122    240.237419
2   FBgn0264373 56      0
3   FBgn0027570 54      0

説明する

  • -a:自動的に各行を配列に分割します@F

  • BEGIN {$" = "\t"}:リスト区切り記号をtabに設定しました\t。これは、二重引用符で囲まれた文字列内に配列または配列スライスを挿入するときに使用されます。

  • print "@{[@F]}" and next if $. == 1:タイトルを印刷して次の行に進みます。

  • $F[1] = $1 if /_([^:]*):/_:最初の値と間の値を取得し:て、2番目の要素に保存します@F

  • print "@{[@F]}":希望の出力を印刷します。

答え3

sed -e 'h;s/.*intron_[^:]*\(:[^[:space:]]*\).*/\1/;s/./ /g;;G;;s/\(.*\)\n\(.*\)intron_\([^:]*\):[^[:space:]]*/\2\3\1/' YourFile

1 sed(パイプなし)に列を保存します。保持バッファを使用します。

Posixバージョン(--posixまたGNU sed)

関連情報