我有一个这样的文件:
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
您可以选择一个匹配的模式,每行显示一个,如下所示
grep -oE '\<chr[[:digit:]]+_[[:digit:]]+' file
正则表达式可以这样分解
\<
- 匹配单词的开头chr
- 文字字符[[:digit:]]+
- 一位或多位(+
)数字_
- 文字下划线
答案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
,然后将所有空格和下划线转换为制表符(从结果中删除连续的制表符),剪切出所需的列,用第二个 将列转换为单独的行tr
,然后使用paste
重建数据最终结果。