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

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

次のようなファイルがあります:

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 番目の列では、と 1 番目の列の間の文字列 (常に とは限らず、他の名前の場合もあります)target_idのみを保持します。そのため、新しい出力ファイルでは列 2 の値が単純化されますが、ファイルの残りの部分は同じままです。FBgnXXXXintron_:

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

答え1

sedと の使用column:

$ 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

この重要な部分は、substitute コマンドです。

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"}: リスト区切り文字をタブに設定します\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 バージョン ( --posixGNU sed と同様)

関連情報