Linux下如何用sed或awk为正负小数前添加空格?
基因数据文本字段分隔解决方案
原始输入文件内容
GENERSID1RSID2VALUE ENSG00000242220rs2826052rs28260520.20961262553802 ENSG00000242220rs2826052rs798932040.00583452893352463 ENSG00000242220rs2826052rs117256228-0.003012912482066
期望输出格式
GENE RSID1 RSID2 VALUE ENSG00000242220 rs2826052 rs2826052 0.20961262553802 ENSG00000242220 rs2826052 rs79893204 0.00583452893352463 ENSG00000242220 rs2826052 rs117256228 -0.003012912482066
问题分析
你之前的sed命令仅处理了rs前缀和负小数-0.的分隔,但未覆盖正小数0.的情况,同时表头的RSID2VALUE也未分割。
解决方案
方案1:改进sed命令(一次完成所有分隔)
使用多规则正则替换,同时处理表头、RSID字段、正负小数的分隔:
sed -e 's/rs/ &/g' \ -e 's/\(rs[0-9]*\)\(-0\.\)/\1 \2/' \ -e 's/\(rs[0-9]*\)\(0\.\)/\1 \2/' \ -e 's/RSID2VALUE/RSID2 VALUE/' \ Model_training_chr21_covariances.txt > Model_training_chr21_covariances_fixed.txt
各规则作用:
s/rs/ &/g:在所有rs前缀前添加空格,分割GENE与RSID1、RSID1与RSID2s/\(rs[0-9]*\)\(-0\.\)/\1 \2/:在RSID2与负小数-0.之间添加空格s/\(rs[0-9]*\)\(0\.\)/\1 \2/:在RSID2与正小数0.之间添加空格s/RSID2VALUE/RSID2 VALUE/:分割表头的最后两个字段
方案2:使用awk处理(更稳定)
如果数据字段结构固定(GENE、RSID1、RSID2、VALUE),用awk正则匹配分割更可靠:
awk '{ match($0, /^([^rs]+)(rs[^rs]+)(rs[^0-9-]+)(.*)/, arr); print arr[1], arr[2], arr[3], arr[4] }' Model_training_chr21_covariances.txt > output.txt
正则匹配逻辑:
^([^rs]+):匹配第一个rs前的GENE字段(rs[^rs]+):匹配第一个完整的RSID1字段(rs[^0-9-]+):匹配第二个完整的RSID2字段(到数值开头的0/-前结束)(.*):匹配剩余的VALUE数值部分
内容的提问来源于stack exchange,提问作者Rhea Bedi
相关产品推荐
相关产品推荐

