特定の部分文字列の抽出

特定の部分文字列の抽出

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

RSID1 RSID2
chr1_169894240_G_T_b38  chr1_169894240_G_T_b38
chr1_169894240_G_T_b38  chr1_169891332_G_A_b38
chr1_169891332_G_A_b38  chr1_169891332_G_A_b38
chr1_169661963_G_A_b38  chr1_169661963_G_A_b38
chr1_169661963_G_A_b38  chr1_169697456_A_T_b38
chr1_169697456_A_T_b38  chr1_169697456_A_T_b38
chr1_27636786_T_C_b38   chr1_27636786_T_C_b38
chr1_196651787_C_T_b38  chr1_196651787_C_T_b38
chr6_143501715_T_C_b38  chr6_143501715_T_C_b38

次の情報を抽出したいと思いますchr1_169894240 chr1_169894240。私は他のことを知りたくありません。chr_pos長さが異なるため、この情報を抽出する方法は混乱します。ある場合には長さが9で、他の場合には長さが10である。したがって、cut特定の値を表示するためにコマンドを使用すると、作成された値が表示されますが、chr_pos一部の値は表示されません。chr_pos_誰でもこの問題を解決するのに役立ちますか?

答え1

awkを使用してください:

awk 'NR >1 {split($1, array, "_"); print array[1] "_" array[2]; split($2, array, "_"); print array[1] "_" array[2]}' FILE

答え2

GNUがある場合は、grep次のように1行に1つずつ一致するパターンを選択できます。

grep -oE '\<chr[[:digit:]]+_[[:digit:]]+' file

正規表現は次のように分割できます。

  • \<- 単語の先頭に一致
  • chr- テキスト文字
  • [[:digit:]]+- 1つ以上の+数字()
  • _- テキストの下線

答え3

必要なフィールドを選択するには、cutバンクと区切り文字を使用する必要があり、単一文字の区切り文字のみがサポートされているため、ここでは実際には使用できません。_cut

代わりに使用してくださいawk

awk -F '[[:blank:]_]+' 'NR > 1 { $0 = sprintf("%s_%d %s_%d", $1, $2, $6, $7) }; 1' file

これは、入力をスペースまたはアンダースコアで区切られたフィールドを含む行として扱います。最初の行のタイトルは変更されずに残りますが、他の行は1番目、2番目、6番目、7番目のスペース、または下線で区切られたフィールドを使用して書き換えられます。


あなたできるを使用してくださいcut。しかし、少し汚れてヘッダーが失われます。

tail -n +2 file | tr -s '[:blank:]_' '[\t*]' | cut -f 1,2,6,7 | tr '\t' '\n' | paste -d '_ ' - - - -

これは、入力の最初の行を削除tailし、すべてのスペースとアンダースコアをタブに変換し(結果から連続タブを削除し)、目的の列を切り取り、列を2行目の別々の列に変換し、再構成されたtrデータpasteを使用します。結果を仕上げます。

関連情報