如何有效地总结以下列?
第1栏
1
3
3
...
第2栏
2323
343
232
...
这应该给我
预期结果
2324
346
235
...
我有两个文件中的列。
我有时会使用太多大括号,以至于我在我的文件中使用了一个{than this}。 我试图找到我使用了一个不必要的花括号的地方。 我在获取数据时使用了以下步骤
查找命令
find . * -exec grep '{' {} + > /tmp/1
find . * -exec grep '}' {} + > /tmp/2
AWK命令
awk -F: '{ print $2 }' /tmp/1 > /tmp/11
awk -F: '{ print $2 }' /tmp/2 > /tmp/22
该列位于文件/ tmp / 11和/ tmp / 22中。
我在我的程序中重复了很多类似的命令。 这告诉我,这不是正确的方法。
请指教我,如Python,Perl或任何可以减少步骤数量的Unix工具。
答案 0 :(得分:11)
使用python:
totals = [ int(i)+int(j) for i, j in zip ( open(fname1), open(fname2) ) ]
答案 1 :(得分:11)
如果c1和c2是你的文件,你可以这样做:
$ paste c1 c2 | awk '{print $1 + $2}'
或(没有AWK):
$ paste c1 c2 | while read i j; do echo $(($i+$j)); done
答案 2 :(得分:3)
您可以通过使用同时进行计数和比较的命令来避免中间步骤:
find . -type f -exec perl -nle 'END { print $ARGV if $h{"{"} != $h{"}"} } $h{$_}++ for /([}{])/g' {}\;
每个文件调用一次Perl程序,Perl程序计算每种类型花括号的数量,如果计数不匹配则打印文件名。
您必须小心/([}{]])/
部分,如果您说find
,{}
会认为需要在/([{}]])/
上进行替换。
警告:如果您尝试针对源代码运行此代码,则此代码会出现误报和否定。请考虑以下情况:
平衡,但用字符串表示:
if ($s eq '{') {
print "I saw a {\n"
}
不平衡,但是字符串:
while (1) {
print "}";
您可以使用B::Deparse扩展Perl命令:
perl -MO = Deparse -nle'END {print $ ARGV if $ h {“{”}!= $ h {“}”}} $ h {$ _} ++ for /([} {]) / G'
结果是:
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
sub END {
print $ARGV if $h{'{'} != $h{'}'};
}
;
++$h{$_} foreach (/([}{])/g);
}
我们现在可以查看该计划的每一部分:
BEGIN { $/ = "\n"; $\ = "\n"; }
这是由-l
选项引起的。它将输入和输出记录分隔符设置为“\ n”。这意味着读入的任何内容都将被分成基于“\ n”的记录,并且任何print语句都会附加“\ n”。
LINE: while (defined($_ = <ARGV>)) {
}
这是由-n
选项创建的。它遍历通过命令行传入的每个文件(如果没有文件传递则传递给STDIN)读取这些文件的每一行。这也恰好将$ARGV
设置为<ARGV>
读取的最后一个文件。
chomp $_;
这将删除刚刚读取的行$/
变量中的任何内容($_
),它在此处没有任何用处。它是由-l
选项引起的。
sub END {
print $ARGV if $h{'{'} != $h{'}'};
}
这是一个END块,此代码将在程序结束时运行。如果存储在与$ARGV
和%h
键相关联的'{'
中的值相等,则会打印'}'
(上次读取的文件的名称,见上文)。
++$h{$_} foreach (/([}{])/g);
这需要进一步细分:
/
( #begin capture
[}{] #match any of the '}' or '{' characters
) #end capture
/gx
是一个正则表达式,它返回匹配的字符串中的“{”和“}”字符列表。由于没有指定字符串,因此将匹配$_
变量(保存最后一次从文件中读取的行,见上文)。该列表被输入foreach
语句,该语句然后运行列表中每个项目(因此名称)前面的语句。它还将$_
(如您所见,$_
是Perl中的常用变量)设置为列表中的项目。
++h{$_}
此行将与$_
相关联的$ h中的值(将为'{'或'}',见上文)增加一个。
答案 3 :(得分:1)
在Python(或Perl,Awk,&amp; c)中你可以在一个单独的“通行证”中合理地做到这一点 - 我不确定你的意思是“太多大括号”,但你可以肯定会计算每个文件的卷曲使用。例如(除非您不得不担心多GB文件),使用大多数花括号的10个文件:
import heapq
import os
import re
curliest = dict()
for path, dirs, files in os.walk('.'):
for afile in files:
fn = os.path.join(path, afile)
with open(fn) as f:
data = f.read()
braces = data.count('{') + data.count('}')
curliest[fn] = bracs
top10 = heapq.nlargest(10, curlies, curliest.get)
top10.sort(key=curliest.get)
for fn in top10:
print '%6d %s' % (curliest[fn], fn)
答案 4 :(得分:0)
回复Lutz'n回答
我的问题终于被这个社区解决了
paste -d: /tmp/1 /tmp/2 | awk -F: '{ print $1 "\t" $2 - $4 }'
答案 5 :(得分:0)
只需1个awk命令即可解决您的问题...
awk '{getline i<"file1";print i+$0}' file2