Linux 中两个文件的值相减
Subtracting values on two files in Linux
我有两个包含数字和文本的文件。两个文件中的文本是相同的。我想创建一个新文件,其中包含两个文件的平均数。
FileA.txt(超过10000行和超过1000个文字和数字)
textA
textB(10,2,2)
textC(2)
textD
.
.
FileB.txt(文本与 FileA.txt 相同)
textA
textB(0,0,4)
textC(4)
textD
.
.
FileNew.txt(有 FileA 和 FileB.txt 的平均值)
textA
textB(5,1,3)
textC(3)
textD
.
.
一个请求是我不想更改任何文本。只需要更改数字。
我认为 AWK 或 diff 可以胜任这项工作。
最佳,
在玹
TXR解法:
@(next :list @(weave (get-lines (open-file [*args* 0]))
(get-lines (open-file [*args* 1]))))
@(repeat)
@ (cases)
@text(@cnum0)
@text(@cnum1)
@ (do (let* ((num0 [mapcar toint (split-str cnum0 ",")])
(num1 [mapcar toint (split-str cnum1 ",")])
(avg (mapcar (op trunc (+ @1 @2) 2) num0 num1)))
(put-line `@text(@{avg ","})`)))
@ (or)
@text
@text
@ (do (put-line text))
@ (end)
@(end)
$ txr avg.txr FileA.txt FileB.txt
textA
textB(5,1,3)
textC(3)
textD
.
.
此脚本处理这些文件,就好像它们是一个文件,其中包含来自两个文件的行 interleaved。相应的文本必须完全匹配,否则程序会以失败的终止状态停止。与 text(whatever)
语法不匹配的行被假定为必须完全匹配的文本。
假定数字为整数,求平均采用截断除法
这个纯 Lisp 解决方案简单地将行分成数字和非数字部分,平均相应的数字部分。使用浮点数学。 tok-str
中的 t
参数告诉它保留与标记化正则表达式不匹配的中间部分。
(each ((line0 (get-lines (open-file [*args* 0])))
(line1 (get-lines (open-file [*args* 1]))))
(let* ((nregex #/(\d+|\d+\.\d+|\.\d+)([Ee][+\-]?\d+)?/)
(chop0 (tok-str line0 nregex t))
(chop1 (tok-str line1 nregex t))
(out (mapcar (lambda (tok0 tok1)
(let ((n0 (tofloat tok0))
(n1 (tofloat tok1)))
(if (and n0 n1)
(/ (+ n0 n1) 2)
tok0)))
chop0 chop1)))
(put-line `@{out ""}`)))
$ txr avg.tl FileA.txt FileB.txt
textA
textB(5.0,1.0,3.0)
textC(3.0)
textD
.
.
也许您可以这样尝试:
paste 'FileA' 'FileB'|awk '{if([=10=]!~/\([0-9]+,[0-9]+,[0-9]+\)/){print ;next}{split(,f1,/[(),]/);split(,f2,/[(),]/)};print f1[1] "(",int((f1[2]+f2[2])/2) "," int((f1[3]+f2[3])/2) "," int((f1[4]+f2[4])/2) ")"}'
以可读的方式对其进行分解
创建一个名为 awkscript
的文件并附加这些行
#!/usr/bin/awk
{
if([=11=]!~/\([0-9]+,[0-9]+,[0-9]+\)/){
print ;next}
{split(,f1,/[(),]/);split(,f2,/[(),]/)};
print f1[1] "(",int((f1[2]+f2[2])/2) "," int((f1[3]+f2[3])/2) "," int((f1[4]+f2[4])/2) ")"
}
现在像
一样调用你的脚本
paste 'FileA' 'FileB'|awk -f 'awkscript'
(粘贴在这里派上用场)
结果
textA
textB( 5,1,3)
textC(2)
textD
.
.
我有两个包含数字和文本的文件。两个文件中的文本是相同的。我想创建一个新文件,其中包含两个文件的平均数。
FileA.txt(超过10000行和超过1000个文字和数字)
textA
textB(10,2,2)
textC(2)
textD
.
.
FileB.txt(文本与 FileA.txt 相同)
textA
textB(0,0,4)
textC(4)
textD
.
.
FileNew.txt(有 FileA 和 FileB.txt 的平均值)
textA
textB(5,1,3)
textC(3)
textD
.
.
一个请求是我不想更改任何文本。只需要更改数字。
我认为 AWK 或 diff 可以胜任这项工作。
最佳,
在玹
TXR解法:
@(next :list @(weave (get-lines (open-file [*args* 0]))
(get-lines (open-file [*args* 1]))))
@(repeat)
@ (cases)
@text(@cnum0)
@text(@cnum1)
@ (do (let* ((num0 [mapcar toint (split-str cnum0 ",")])
(num1 [mapcar toint (split-str cnum1 ",")])
(avg (mapcar (op trunc (+ @1 @2) 2) num0 num1)))
(put-line `@text(@{avg ","})`)))
@ (or)
@text
@text
@ (do (put-line text))
@ (end)
@(end)
$ txr avg.txr FileA.txt FileB.txt
textA
textB(5,1,3)
textC(3)
textD
.
.
此脚本处理这些文件,就好像它们是一个文件,其中包含来自两个文件的行 interleaved。相应的文本必须完全匹配,否则程序会以失败的终止状态停止。与 text(whatever)
语法不匹配的行被假定为必须完全匹配的文本。
假定数字为整数,求平均采用截断除法
这个纯 Lisp 解决方案简单地将行分成数字和非数字部分,平均相应的数字部分。使用浮点数学。 tok-str
中的 t
参数告诉它保留与标记化正则表达式不匹配的中间部分。
(each ((line0 (get-lines (open-file [*args* 0])))
(line1 (get-lines (open-file [*args* 1]))))
(let* ((nregex #/(\d+|\d+\.\d+|\.\d+)([Ee][+\-]?\d+)?/)
(chop0 (tok-str line0 nregex t))
(chop1 (tok-str line1 nregex t))
(out (mapcar (lambda (tok0 tok1)
(let ((n0 (tofloat tok0))
(n1 (tofloat tok1)))
(if (and n0 n1)
(/ (+ n0 n1) 2)
tok0)))
chop0 chop1)))
(put-line `@{out ""}`)))
$ txr avg.tl FileA.txt FileB.txt
textA
textB(5.0,1.0,3.0)
textC(3.0)
textD
.
.
也许您可以这样尝试:
paste 'FileA' 'FileB'|awk '{if([=10=]!~/\([0-9]+,[0-9]+,[0-9]+\)/){print ;next}{split(,f1,/[(),]/);split(,f2,/[(),]/)};print f1[1] "(",int((f1[2]+f2[2])/2) "," int((f1[3]+f2[3])/2) "," int((f1[4]+f2[4])/2) ")"}'
以可读的方式对其进行分解
创建一个名为 awkscript
的文件并附加这些行
#!/usr/bin/awk
{
if([=11=]!~/\([0-9]+,[0-9]+,[0-9]+\)/){
print ;next}
{split(,f1,/[(),]/);split(,f2,/[(),]/)};
print f1[1] "(",int((f1[2]+f2[2])/2) "," int((f1[3]+f2[3])/2) "," int((f1[4]+f2[4])/2) ")"
}
现在像
一样调用你的脚本paste 'FileA' 'FileB'|awk -f 'awkscript'
(粘贴在这里派上用场)
结果
textA
textB( 5,1,3)
textC(2)
textD
.
.