Linux 按特定分隔符删除字符串
我在一个文件中有几列,其中第二列有“:”分隔符,我想删除第二列中的第一、第三和第四个字符串,并将第二个字符串保留在该列中。但是我有正常的分隔符空间,所以我不知道Linux 按特定分隔符删除字符串,linux,bash,awk,sed,Linux,Bash,Awk,Sed,我在一个文件中有几列,其中第二列有“:”分隔符,我想删除第二列中的第一、第三和第四个字符串,并将第二个字符串保留在该列中。但是我有正常的分隔符空间,所以我不知道 input: --- 22:16050075:A:G 16050075 A G --- 22:16050115:G:A 16050115 G A --- 22:16050213:C:T 16050213 C T --- 22:16050319:C:T 16050319 C T --- 22:16050527:C:A 16050527
input:
--- 22:16050075:A:G 16050075 A G
--- 22:16050115:G:A 16050115 G A
--- 22:16050213:C:T 16050213 C T
--- 22:16050319:C:T 16050319 C T
--- 22:16050527:C:A 16050527 C A
desired output:
--- 22 16050075 16050075 A G
--- 22 16050115 16050115 G A
--- 22 16050213 16050213 C T
--- 22 16050319 16050319 C T
--- 22 16050527 16050527 C A
Wrong:
cat df.txt | awk -F: '{print $1, $3, $6, $7, $8}'
--- 22 A
--- 22 G
--- 22 C
--- 22 C
--- 22 C
但我做不好。awk和sed命令可以做到吗
谢谢。只需在
$2
上使用POSIX
兼容的split()
函数即可
awk '{split($2,temp,":"); $2=temp[2];}1' file
--- 16050075 16050075 A G
--- 16050115 16050115 G A
--- 16050213 16050213 C T
--- 16050319 16050319 C T
--- 16050527 16050527 C A
将列2拆分为de limiter:
,将$2
值更新为所需元素(temp[2]
),并打印其余字段({}1
基于FS
重新构造所有单个字段并打印)
建议不要使用多个解除限制器,因为它会改变单个字段的绝对位置,而split()
可以很容易地保留位置并提取所需的值
对于添加新列的更新需求,只需执行以下操作
awk '{split($2,temp,":"); $2=temp[1] FS temp[2];}1' file
--- 22 16050075 16050075 A G
--- 22 16050115 16050115 G A
--- 22 16050213 16050213 C T
--- 22 16050319 16050319 C T
--- 22 16050527 16050527 C A
或者,如果您有
gnuawk
/gawk
,您可以将其gensub()
用于正则表达式(使用POSIX
字符类[[:digit]]]
)的提取,如下所示:
awk '{$2=gensub(/^([[:digit:]]+):([[:digit:]]+).*$/,"\\1 \\2","g",$2);}1' file
--- 22 16050075 16050075 A G
--- 22 16050115 16050115 G A
--- 22 16050213 16050213 C T
--- 22 16050319 16050319 C T
--- 22 16050527 16050527 C A
gensub(/^([[:digit:][]+):([[:digit:][]+).$/,“\\1\\2”,“g”,“2美元)
part仅捕获前两个受限制的字段:
使用捕获组\\1
和\\2
并打印其余字段。您也可以尝试以下方法,以替代@Inian更好、更便携的解决方案-
awk -F '[ :]' '{print $1, $3, $6, $7, $8}' file
其中文件
包含您的初始输入
输出-
--- 16050075 16050075 A G
--- 16050115 16050115 G A
--- 16050213 16050213 C T
--- 16050319 16050319 C T
--- 16050527 16050527 C A
编辑
随着输入文件(附加列编号2)的更改,上述命令可以更改为-
awk -F '[ :]' '{print $1, $2, $3, $6, $7, $8}' file
输出
--- 22 16050075 16050075 A G
--- 22 16050115 16050115 G A
--- 22 16050213 16050213 C T
--- 22 16050319 16050319 C T
--- 22 16050527 16050527 C A
您也可以使用sed:
sed -r 's/..:([^:]+)[^ ]+/\1/' file
我试过上面的方法。如果我打印--22 16050075 16050075 A G--22 16050115 16050115 G A--22 16050213 16050213 C t--22 16050319 16050319 C t--22 16050527 16050527 C如果你错过了$2列,只需添加它。@ClaesWikner,OP更改了输入文件。我现在改变了命令。谢谢你的提醒。