次のファイルがあります。
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
使用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
ここで重要な部分は交換コマンドです。
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)