我有一个看起来像2列(空格分隔)的文件:
chr1.21.imputed_info:1 100880328
chr1.31.imputed_info:1 10566215
chr1.23.imputed_info:--- 110198129
chr1.23.imputed_info:--- 114445880
chr1.24.imputed_info:--- 118141492
chr1.25.imputed_info:--- 120257110
chr1.25.imputed_info:1 121280613
chr1.30.imputed_info:--- 121287994
chr1.30.imputed_info:--- 145604302
我想从1-22和第二列中提取“chr”之后的数字。所以我的输出看起来像这样:
1 100880328
1 10566215
1 110198129
1 114445880
1 118141492
1 120257110
1 121280613
1 121287994
1 145604302
一些重要的考虑因素:
chr1,chr2等后面的数字可能会超过50个。所以你可以有chr1.50,或chr2.45等
column1末尾的“info:”部分可能看起来像信息:1,信息:2 ..信息:22或信息:---
我在Bash中提出了这个问题:
cat file.txt | sed 's/chr//g' | sed 's/.imputed_info://g'
这让我非常接近,但它确实如此:
1.211 100880328
1.31 10566215
1.23--- 110198129
1.23--- 114445880
1.24--- 118141492
1.25--- 120257110
1.251 121280613
1.25--- 121287994
1.30--- 145604302
1.301 149906413
我知道有很多方法可以在R和Python中做到这一点,但我应该说这是一个巨大的文件,所以通过Bash会节省很多时间..所以,如果有人有一个很好的(理想的清洁解决方案 - 我做意识到我的sed命令有点难看。这会很棒。感谢。
答案 0 :(得分:5)
缩短方式:
sed 's/^chr//;s/\..* / /' filename
修改强>
翻译:删除领先" chr" (如果它在那里),并替换第一个'。'中的所有内容。到最后一个空格(即'。'后跟任何内容,后跟'')只有一个空格。
答案 1 :(得分:3)
sed 's/chr\([0-9]*\)[^ ]*[ ]*\([0-9]*\)/\1\t\2/' file.txt
答案 2 :(得分:3)
我会使用awk
:
awk -F'[. ]' '{print substr($1,4), $NF}' file.txt
用点或空格分割每一行并打印第一个字段,从第4个字符和最后一个字段开始。 (NF
是字段数,$NF
是最后一个字段)
输出:
1 100880328
1 10566215
1 110198129
1 114445880
1 118141492
1 120257110
1 121280613
1 121287994
1 145604302
答案 3 :(得分:1)
sed 's/chr\([^.]*\).* /\1 /' file
在适用所有条件的情况下使用sed
:
sed 's/^chr\(1[1-9]\{0,1\}\|10\|2[012]\)\.\(1[1-9]\{0,1\}\|10\|[234][0-9]\|50\)[^ ]* *\([^ ]*\)/\1 \3/' file
仅使用sed
以下语法:
sed 's/^chr\([1-9][1-9]*\)\.[1-9][1-9]*[^ ]* *\([^ ]*\)/\1 \2/' file
使用awk
:
awk '
/^chr([0-9]+)\.[0-9]+/{
match($1, /[0-9]+/);
$1 = substr($1, RSTART, RLENGTH);
print;
}' file
输出:
1 100880328
1 10566215
1 110198129
1 114445880
1 118141492
1 120257110
1 121280613
1 121287994
1 145604302
答案 4 :(得分:1)
假设你已经使用扩展的正则表达式:
sed -r -n 's/chr(2[0-2]|1?[0-9])\..+\s([0-9]+)/\1 \2/p' file.txt
如果chr
之后的数字不能高于22,则可以简化(无需扩展正则表达式)表达式
sed -r 's/chr([0-9]+)\..+\s([0-9]+)/\1 \2/' file.txt
正则表达式解释
chr
- 文字匹配(2[0-2]|1?[0-9])
- 第一个匹配组
2[0-2]
- 20至22 |
或(如果不是20-22,则测试组中的下一个表达式)1?
- 零或一1
[0-9]
- 0-9 \.
- 字面点.+\s
- 一个或多个字符后跟空格字符 ([0-9]+)
- 第二个匹配组,匹配一个或多个数字
/\1 \2/
- 替换为第一个和第二个匹配组
<强>结果强>
我将你的例子扩展到了
chr1.21.imputed_info:1 100880328
chr2.31.imputed_info:1 10566215
chr11.23.imputed_info:--- 110198129
chr12.23.imputed_info:--- 114445880
chr22.24.imputed_info:--- 118141492
chr1.25.imputed_info:--- 120257110
chr1.25.imputed_info:1 121280613
chr1.30.imputed_info:--- 121287994
chr1.30.imputed_info:--- 145604302
sed
的输出是:
1 100880328
2 10566215
11 110198129
12 114445880
22 118141492
1 120257110
1 121280613
1 121287994
1 145604302