从文件中复制某些空格

从文件中复制某些空格

我有一个看起来像这样的文件

   18DMA      H 9996   0.886   5.687   5.320
   18DMA      H 9997   1.019   5.764   5.247
   18DMA     Np 9998   0.947   5.584   5.151
   18DMA      H 9999   1.033   5.541   5.113
   18DMA     Cn10000   0.880   5.674   5.050
   18DMA      H10001   0.831   5.616   4.971
   18DMA      H10002   0.814   5.751   5.091
   18DMA      H10003   0.957   5.735   5.003
   18DMA     Cn10004   0.837   5.486   5.185

期望的输出是删除第 3 列,但是由于从某一行/行开始,接下来的原子名称和编号之间没有空格,我无法按列进行删除。有没有办法通过选择一定数量的字符来进行删除?期望输出应该是

   18DMA      H    0.886   5.687   5.320
   18DMA      H    1.019   5.764   5.247
   18DMA     Np    0.947   5.584   5.151
   18DMA      H    1.033   5.541   5.113
   18DMA     Cn    0.880   5.674   5.050
   18DMA      H    0.831   5.616   4.971
   18DMA      H    0.814   5.751   5.091
   18DMA      H    0.957   5.735   5.003
   18DMA     Cn    0.837   5.486   5.185

答案1

cut在字符模式下使用:

cut -c1-15,21-

您可能需要调整确切的字符数。同样,这假设输入不使用制表符(\t字符)作为分隔符(它可能不会,因为这样您一开始就不会遇到连接字段的问题)。

如果有制表符,那么expand程序可以将它们转换为空格。

答案2

假设您没有<TAB>s 但有多个空格作为字段分隔符,通过查看和计算示例数据,我想出了

  $ sed -E 's/^(.{15}).{5}/\1/' file
   18DMA      H   0.886   5.687   5.320
   18DMA      H   1.019   5.764   5.247
   18DMA     Np   0.947   5.584   5.151
   18DMA      H   1.033   5.541   5.113
   18DMA     Cn   0.880   5.674   5.050
   18DMA      H   0.831   5.616   4.971
   18DMA      H   0.814   5.751   5.091
   18DMA      H   0.957   5.735   5.003
   18DMA     Cn   0.837   5.486   5.185

它对前 15 个字符使用“反向引用”,以便在 ubstitute 命令\1 的替换部分中使用它们来恢复它们s

答案3

$ awk -v OFS='\t' 'NF == 5 { sub("[0-9]*$", "", $2) } NF == 6 { $0 = $1 OFS $2 OFS $4 OFS $5 OFS $6 } { print }' file
18DMA   H       0.886   5.687   5.320
18DMA   H       1.019   5.764   5.247
18DMA   Np      0.947   5.584   5.151
18DMA   H       1.033   5.541   5.113
18DMA   Cn      0.880   5.674   5.050
18DMA   H       0.831   5.616   4.971
18DMA   H       0.814   5.751   5.091
18DMA   H       0.957   5.735   5.003
18DMA   Cn      0.837   5.486   5.185

这个简短的awk程序将对输入行执行不同的操作,具体取决于输入行是否包含 5 个或 6 个空格分隔的字段。

如果它包含五个字段,它将删除第二个字段末尾的所有数字,并将其余部分保留原样。如果它包含六个字段,它将重写该行但省略第三个字段。

输出将以制表符分隔(或由您OFS在命令行上设置的任何内容分隔)。

答案4

如果我是你,我会首先“修复”原始内容,然后简单地删除该列。不过,您可以一次完成这两项操作:

awk '{sub(/[0-9]+/," &",$2); $0=$0; $3=""; print}' input_file

18DMA H  0.886 5.687 5.320
18DMA H  1.019 5.764 5.247
18DMA Np  0.947 5.584 5.151
18DMA H  1.033 5.541 5.113
18DMA Cn  0.880 5.674 5.050
18DMA H  0.831 5.616 4.971
18DMA H  0.814 5.751 5.091
18DMA H  0.957 5.735 5.003
18DMA Cn  0.837 5.486 5.185

$0=$0分配将导致awk重新计算(并重新分割)当前行。与所有其他答案不同,这仅假设第二个字段的可能格式,而不假设字段的长度或数量。

使用 Tab 作为输出字段分隔符的版本:

awk -vOFS='\t' '{sub(/[0-9]+/," &",$2); $0=$0; $3=""; sub(OFS OFS,OFS); print}' input_file

18DMA   H       0.886   5.687   5.320
18DMA   H       1.019   5.764   5.247
18DMA   Np      0.947   5.584   5.151
18DMA   H       1.033   5.541   5.113
18DMA   Cn      0.880   5.674   5.050
18DMA   H       0.831   5.616   4.971
18DMA   H       0.814   5.751   5.091
18DMA   H       0.957   5.735   5.003
18DMA   Cn      0.837   5.486   5.185

额外的内容sub(OFS OFS, OFS)将折叠由 所创建的空字段$3=""。仅当文件由专门需要制表符分隔字段的工具处理或出于美观原因时才需要这样做。

相关内容