如何合并两列中的值?

如何合并两列中的值?

我有一个以下格式的文件:

$ cat /tmp/raw
2015-01   5000   1000
2015-02   6000   2000
2015-03   7000   3000

现在,我想要的是从每行的第 2 列和第 3 列中获取组合值,结果如下:

2015-01   6000
2015-02   8000
2015-03   9000

我尝试了这个,但它只显示文件中的最后一个值,例如 2015-03 值。

答案1

有以下几种方法:

  1. 另一种 awk 方法

    awk '{$2+=$3;}NF--' file
    
  2. Perl

    perl -lane 'print "$F[0] ",$F[1]+$F[2]' file
    

    或者

    perl -ape 's/$F[1].*/$F[1]+$F[2]/e' file
    
  3. Shell(比上面慢得多/效率低得多)

    while read a b c; do echo "$a $((b + c))"; done < file
    

答案2

您可以尝试使用awk

awk '{ print $1, $2 + $3; }' /tmp/raw

结果将是(我认为 2015-03 的值应该是 10000):

2015-01 6000
2015-02 8000
2015-03 10000

答案3

sed 's/[^ ]* */[&]P/;s//&+pc/3'|dc

...印刷...

2015-01   6000
2015-02   8000
2015-03   10000

所以上面我声明了一个正则表达式它定义了一个场范围由一个*可变长度单个字符序列是^不是 <空格>紧接着是*可变长度单个字符序列是<空格>。此声明应用于 的sed模式空间,它是一个分隔的字符串(默认情况下)由输入中出现的每个\newline 字符进行递归替换(默认情况下)每次出现相同的情况时都会使用下一个。

该声明的接口有两层,每个级别都由最后一个 国际IEEE官方标准委员会确保sed命令语法的可预测应用。sed的 API 语法例如,在这种情况下与/地址/命令一起应用sed s///(这始终是任何替换命令的第一个组成部分),但是相同的内容被更基本的 API 解释为指定的内容的子集regcomp()函数在标准C库

我可以自信地做出这些陈述,sed因为不是只是一个程序,但是,sed在我的类 Unix 机器上命名的已编译可执行文件是一个执行定义明确、历史悠久且受标准控制的sed 应用我的系统的正则表达式匹配库。


sed规格来看:

公用事业sed应支持XBD 基本正则表达式...

...我们在哪里找到...

POSIX.1-2008 系统接口卷中的正则表达式匹配接口支持 BRE 和 EREregcomp(),regexec(),以及相关功能。

一个应用程序调用regcomp()将呈现它一个图案字符串和...

...[这regcomp()函数应编译指向的字符串中包含的正则表达式图案论证并将结果放入结构中预浸料...

为了对此采取行动,所述申请将参考regcomp()的伴侣功能...

...[这regexec()函数比较由指定的空终止字符串细绳与编译的正则表达式预浸料由先前的调用初始化regcomp()...

...regexec()应使用子字符串的偏移量填充 [an] 数组的元素细绳对应于\(带括号的子表达式\)图案...图案本身算作子表达式...

...[这regexec()函数必须填写全部匹配要点匹配, 在哪里匹配匹配由应用程序提供,即使某些元素匹配不对应于子表达式图案


所以当我这样做时...

/[^ ]* */

...sed第一的编译正则表达式并将结果存储在内存中,然后根据需要多次将存储在那里的编译自动机应用到我的模式空间的内容,以满足我的命令。每次执行的结果都是一个由一个或多个空分隔的数组领域在返回的偏移量处分隔regexec()

当我这样做时...

//

...指示应使用最近定义的正则表达式,sed只需调用regexec()再次重用预编译的正则表达式,但这次可能将其应用于更改的细绳论证或应用新的匹配参数按照我的命令。

更具体地说还是...

  • s/[^ ]* */[&]P/
    • 替换第一次出现的图案在模式空间中,先是[左方括号,然后是&它本身,然后是]右方括号,后跟一个P字符。
  • s//&+pc/3
    • 再次将最后使用的正则表达式应用到当前模式空间,并替换3第三次出现的图案在模式空间中,其&自身后跟附加字符串+pc

因此,对于 的每一行sed输入,它都会写入其标准输出,给出您的示例数据:

[2015-01   ]P5000   1000+pc
[2015-02   ]P6000   2000+pc
[2015-03   ]P7000   3000+pc

这可能看起来很奇怪,但dc计算器会引用字符串在方括号之间的输入中,该P命令将打印堆栈顶部而不附加\newline,然后将其从输入堆栈中弹出。

因此,以第一dc行为例:

  • [2015-01 ]P
    • P打印并弹出堆栈顶部
  • 5000
    • 将数字压5000入栈顶并压入当前栈中的所有元素(现在没有)下降了一位。
  • 1000
    • 同上,但这次主堆栈顶部的数字 5000 被下推 1,成为堆栈上的第二个元素。
  • +
    • 将堆栈顶部的两个数字相加,将这两个数字从堆栈中弹出,并将总和压入堆栈顶部。
    • 这会产生一个仅包含 number 的堆栈6000
    • 如果堆栈顶部的两个元素中的任何一个是[字符串],则这是一个语法错误。
  • p
    • p打印堆栈顶部,后跟附加的\newline,而不将其从堆栈中弹出。
  • c
    • c了解堆栈

相关内容