次のファイルがあります。
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
を使用します。結果を仕上げます。