我有以下格式的文件:
$ cat /tmp/raw
2015-01 5000 1000
2015-02 6000 2000
2015-03 7000 3000
Run Code Online (Sandbox Code Playgroud)
现在,我想要的是从每行的第 2 列和第 3 列中获取组合值,以便结果如下:
2015-01 6000
2015-02 8000
2015-03 9000
Run Code Online (Sandbox Code Playgroud)
我试过了,但它只显示文件中的最后一个值,如 2015-03 值。
ter*_*don 16
这里有几个方法:
另一种 awk 方法
awk '{$2+=$3;}NF--' file
Run Code Online (Sandbox Code Playgroud)珀尔
perl -lane 'print "$F[0] ",$F[1]+$F[2]' file
Run Code Online (Sandbox Code Playgroud)
或者
perl -ape 's/$F[1].*/$F[1]+$F[2]/e' file
Run Code Online (Sandbox Code Playgroud)Shell(比上面的慢得多/效率低得多)
while read a b c; do echo "$a $((b + c))"; done < file
Run Code Online (Sandbox Code Playgroud)tal*_*zin 11
您可以尝试使用awk
:
awk '{ print $1, $2 + $3; }' /tmp/raw
Run Code Online (Sandbox Code Playgroud)
结果将是(我认为 2015-03 的值应该是 10000):
2015-01 6000
2015-02 8000
2015-03 10000
Run Code Online (Sandbox Code Playgroud)
sed 's/[^ ]* */[&]P/;s//&+pc/3'|dc
Run Code Online (Sandbox Code Playgroud)
...印刷...
2015-01 6000
2015-02 8000
2015-03 10000
Run Code Online (Sandbox Code Playgroud)
所以在上面我声明了一个正则表达式,它定义了一个字段范围,它由一个*
可变长度的单个字符序列组成,这些字符^
不是 <space> ,后面紧跟一个*
可变长度的单个字符序列<space>。此声明适用于sed
的模式空间,它是一个字符串,由\n
输入中出现的每个ewline 字符分隔(默认情况下),并且每次出现相同时都会递归替换(默认情况下)下一个。
该声明的接口分为两层,每一层都由至少一个 国际 IEEE 官方标准委员会进行全面监管和指定,以确保sed
命令语法的可预测应用。例如,在这种情况下,sed
的 API 语法与/
address/
命令(它始终是任何sed s///
替换命令的第一个组成部分)一起应用,但是相同的内容被更基本的 API 解释为为regcomp()
功能在标准C库。
我可以自信地做出这些声明,因为sed
是不是只是一个程序,而相反,编译后的可执行文件命名sed
我的类Unix机器是执行的明确定义,在历史上建立的,与标准控制的sed
应用我的系统的regular-的表达式匹配库。
从sed
规范:
该
sed
实用程序应支持XBD 基本正则表达式中描述的 BRE ...
...我们在哪里找到...
无论BREs里面和ERES通过在POSIX.1-2008下的系统接口的体积正则表达式匹配的接口支持
regcomp()
,regexec()
以及相关的功能。
调用的应用程序regcomp()
将向它呈现一个模式字符串和...
...[t]该
regcomp()
函数应编译模式参数指向的字符串中包含的正则表达式,并将结果放入结构preg ...
为了对此采取行动,所述应用程序将引用regcomp()
的伴随功能......
... [T]他
regexec()
函数比较由指定的空值终止字符串,字符串与正则表达式编译预浸由以前调用初始化regcomp()
......
regexec()
应当[一个]阵列的子串的偏移的元素填充字符串对应于\(
括号内的子表达式\)
的图案...图案本身算作一个子表达式...... [T]他
regexec()
函数必须在所有填写nmatch的元素pmatch,其中nmatch和pmatch由应用程序提供的,即使某些元素pmatch不对应的子表达式的模式。
所以当我做...
/[^ ]* */
Run Code Online (Sandbox Code Playgroud)
...sed
首先编译正则表达式并将结果存储在内存中,然后将存储在那里的编译自动机应用到我的模式空间的内容中,以满足我的命令所需的次数。每次执行时,结果都是一个或多个空分隔字段的数组,这些字段以 返回的偏移量分隔regexec()
。
当我这样做...
//
Run Code Online (Sandbox Code Playgroud)
...指示应该使用最近定义的正则表达式,sed
可以regexec()
再次调用重用预编译的正则表达式,但这次可能将其应用于更改的字符串参数或应用新的nmatch参数作为我的命令。
更具体的还是...
s/[^ ]* */[&]P/
[
,然后是&
它本身,然后是]
右方括号,后跟一个P
字符。s//&+pc/3
3
的第三次出现模式在图案空间&
本身,随后所附的字符串+pc
。因此,对于sed
's input 的每一行,它都会写入其标准输出,给定您的示例数据:
[2015-01 ]P5000 1000+pc
[2015-02 ]P6000 2000+pc
[2015-03 ]P7000 3000+pc
Run Code Online (Sandbox Code Playgroud)
这可能看起来很奇怪,但dc
计算器在方括号之间引用其输入中的字符串,并且该P
命令将打印堆栈顶部而不附加\n
ewline,然后将其从输入堆栈中弹出。
因此,以第一行为例,dc
将执行以下操作:
[2015-01 ]P
P
打印并弹出栈顶5000
5000
压入堆栈顶部,并将当前堆栈中的所有元素(现在没有)向下压一。1000
+
6000
。[
字符串,则这是一个语法错误]
。p
p
rint 堆栈的顶部,然后是附加的\n
ewline,而不将其从堆栈中弹出。c
c
了解堆栈