Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 按特定分隔符删除字符串_Linux_Bash_Awk_Sed - Fatal编程技术网

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更改了输入文件。我现在改变了命令。谢谢你的提醒。