【问题标题】:Extracting data from a multicolumn file with missing entries从缺少条目的多列文件中提取数据
【发布时间】:2014-01-10 05:33:01
【问题描述】:

我正在尝试从名为 mass.mas03multicolumn file 中提取一些数据。列由tab 分隔。当数据开始时,您可以看到有空的条目(即第 44 行 VS 第 45 行)。

整个想法是从特定列(MASS EXCESS,即)为多行提取数据,取总和并在 xy 轴系统上创建一条水平线, y 坐标是这些值的总和。

以第 41、65、74 行为例

  -1    0    1    1 H          7288.97050    0.00011      0.0      0.0   B-      *                1 007825.03207    0.00010
   0    4    4    8 Be         4941.672      0.035     7062.435    0.004 B- -17979.819    1.001   8 005305.103      0.037
   4    7    3   10 Li   -n   33050.581     15.124     4531.555    1.512 B-  20443.910   15.123  10 035481.259     16.236

我想做: 7288.97050 + 4941.672 - 33050.581 = - 20819.9385 。如果我使用awk 命令来访问数据,我会遇到这个问题

> awk '/8 Be/ {print $6}' mass.mas03
  4941.672 
>awk '/10 Li/ {print $6}' mass.mas03
  -n

我不知道awk 是否不仅是数据选择以及“情节”的最佳选择,因此我愿意接受建议!

一个明显的解决方案是在需要时使用$7 而不是$6,但它是一个大文件,我正在尝试将整个过程自动化一点。

对于这个奇怪的列文件,有没有办法“选择”所需的数据并对它们应用一些简单的计算?

【问题讨论】:

  • 我怀疑awk 您需要提供-F'\t' 选项以将字段分隔符设置为制表符,然后改用$7
  • 为什么要减去 33050.581(而不是加上)?
  • 如果列由制表符分隔,您可以只检查是否有 1 个或两个连续的制表符,以确定列是否为空..(如 @TLP 所指出的)
  • @TLP:我使用了awk -F'\t' '/10 Li/ {print $7}' mass.mas03awk -F'\t' '/10 Li/ {print $6}' mass.mas03,但我得到了一个空输出。
  • 该文件不是制表符分隔的(它只是列之间的空格)..您需要在将其发送到 awk 之前对其进行后处理

标签: python perl awk


【解决方案1】:

要用制表符替换空格,您可以尝试以下方法:

awk -f f.awk mass.mas03 > mass.mas03.tab

f.awk 在哪里:

/^1N-Z/ {
    f=1
    print
    getline
    print
    next
}
f {
    gsub(/ +/,"\t")
}
{print}

【讨论】:

  • 非常感谢您的回答。这种后处理会使文件有点混乱。如果我输入awk '/He/ {print $7}' mass.mas03.tab,您会再次看到同样的问题,我认为这是由第一列引起的。输出为0.00242 0.00006 11386.233 0.755 26101.038 31598.044 40939.429 ++
  • @Thanos 是的,它不适用于空字段。在这种情况下,它应该插入两个选项卡而不是一个选项卡。我试图弄清楚如何解决这个问题。
  • @非常感谢您的宝贵时间!
  • 如果我在 Excel 上导入 mass.mas03 并按 向左对齐文本,它就可以完成这项工作。如果在 excel 之后,我使用 awk -F'\t' '/H/ {print $8}' mass.mas03 似乎打印了正确的值。现在的问题是如何对文件的特定条目进行简单的计算?
  • @Thanos 太好了.. 你有什么样的计算方法?
【解决方案2】:

如果您的数据确实是制表符分隔的,那么您只需使用:

awk -F'\t' '{ whatever }'

如果是固定宽度的字段,那么您应该使用:

gawk 'BEGIN{FIELDWIDTHS="list of field widths"} { whatever }'

例如:

$ cat file
  -1    0    1    1 H          7288.97050    0.00011
   0    4    4    8 Be         4941.672      0.035
   4    7    3   10 Li   -n   33050.581     15.124

$ gawk 'BEGIN{FIELDWIDTHS="4 5 5 5 5 5 12 12"} {print $7}' file
  7288.970
  4941.672
 33050.581

注意 FIELDWIDTHS 是 gawk 特定的。我不知道这些字段宽度是否适合您的数据,我只是做了一个大概的估计来演示该方法。显然,如果您想将其从固定字段转换为制表符分隔,那么这样做很简单:

$ gawk -v OFS='\t' 'BEGIN{FIELDWIDTHS="4 5 5 5 5 5 12 12"} {$1=$1}1' file
  -1        0       1       1    H                7288.97050        0.00011
   0        4       4       8    Be               4941.672          0.035
   4        7       3      10    Li      -n      33050.581         15.124

如果你想从每个字段中去掉前导/尾随空格:

$ gawk -v OFS='\t' 'BEGIN{FIELDWIDTHS="4 5 5 5 5 5 12 12"} {$1=$1; gsub(/ /,"")}1' file
-1      0       1       1       H               7288.97050      0.00011
0       4       4       8       Be              4941.672        0.035
4       7       3       10      Li      -n      33050.581       15.124

【讨论】:

  • +1 FIELDWIDTHS 似乎是这种输入的好主意,其中空格用于分隔列..
【解决方案3】:

对我来说,文件的结构仍然是字段从一个点开始,在另一个点结束 特定字段始终具有相同数量的字符 所以它是一个固定宽度的字段

$7 从 35 开始,宽度为 12

使用 awk '/Li/ {print substr($0,35,12)}' mass.mas03

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2015-03-18
    • 1970-01-01
    相关资源
    最近更新 更多