关于块选择的问题
-
- 帖子: 22
- 注册时间: 2012-03-09 18:08
关于块选择的问题
文件格式如下所示,每个文件共100行,这里没有全部列出
9.681996 7.000000
8.898758 8.000000
9.681996 10.000000
5.381260 8.000000
9.271999 7.000000
9.514828 9.000000
4.452161 2.000000
8.666753 12.000000
9.914309 12.000000
9.914309 12.000000
左边一列数据不用,要把右边一列数据求平均,我想到的办法是把右边一列复制下来导入LibreOffice Calc或exel中求平均,但若用vim选择块则无法直接在Calc中粘贴,且文件数量众多手动操作太过繁琐。也考虑过用shell script 来实现这一过程,但尝试多次后仍不知如何在shell script中进行块复制。现求教各位高手!
提醒:目的是为了求平均,如果其他方法可以实现也行。如果用shell,若能附上几行代码为例更佳!
在此先写过各位!!!
9.681996 7.000000
8.898758 8.000000
9.681996 10.000000
5.381260 8.000000
9.271999 7.000000
9.514828 9.000000
4.452161 2.000000
8.666753 12.000000
9.914309 12.000000
9.914309 12.000000
左边一列数据不用,要把右边一列数据求平均,我想到的办法是把右边一列复制下来导入LibreOffice Calc或exel中求平均,但若用vim选择块则无法直接在Calc中粘贴,且文件数量众多手动操作太过繁琐。也考虑过用shell script 来实现这一过程,但尝试多次后仍不知如何在shell script中进行块复制。现求教各位高手!
提醒:目的是为了求平均,如果其他方法可以实现也行。如果用shell,若能附上几行代码为例更佳!
在此先写过各位!!!
-
- 帖子: 1453
- 注册时间: 2008-05-24 8:30
Re: 关于块选择的问题
既然打算用 LibreOffice 处理,那么就不要 Vim,也不要 Shell script,直接用 LibreOffice 打开这个文件就行了。
- fanhe
- 帖子: 2357
- 注册时间: 2007-03-24 23:45
Re: 关于块选择的问题
代码: 全选
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
def main():
if not sys.argv[1:]:
return
fileName = sys.argv[1]
cnt = 0
sum = 0.0
with open(fileName) as f:
for l in f:
li = l.strip().split()
if li:
num = float(li[1])
cnt += 1
sum += num
if cnt > 0:
print sum / cnt
else:
print 0
if __name__ == '__main__':
main()
假设你把内容保存为 x.py
就这样用
代码: 全选
python x.py {文本文件}
- lilydjwg
- 论坛版主
- 帖子: 4258
- 注册时间: 2009-04-11 23:46
- 系统: Arch Linux
- 联系:
Re: 关于块选择的问题
把不用的列删掉:
或者把空格换成 Tab 先:
然后使用普通的复制粘贴。Vim 的列选择模式只为 Vim 自己设置的,LibreOffice 不认识,它默认只认Tab。如果你直接用 LibreOffice 打开的话也许你能选择用空格分隔。
另外呢,这个 Vim 内部是可以搞定的,简单的办法是使用 Perl、Ruby、Lua 或者 Python 接口,比如:
注:py3do 为本人加入的命令,补丁见以前的帖子。
Perl 和 Ruby 我都不太会,没试成功。。。Lua 不太好用。
代码: 全选
%s/^.* //
代码: 全选
%s:/ /\t/g
另外呢,这个 Vim 内部是可以搞定的,简单的办法是使用 Perl、Ruby、Lua 或者 Python 接口,比如:
代码: 全选
:py3 s = 0
:py3do global s; s += float(line.split()[-1]):
:py3 print(s / 10)
Perl 和 Ruby 我都不太会,没试成功。。。Lua 不太好用。
- eexpress
- 帖子: 58428
- 注册时间: 2005-08-14 21:55
- 来自: 长沙
- lilydjwg
- 论坛版主
- 帖子: 4258
- 注册时间: 2009-04-11 23:46
- 系统: Arch Linux
- 联系:
Re: 关于块选择的问题
代码: 全选
:perldo $s += $_.split[-1]
:perl VIM::Msg($s / 10)
PS: 当然,如果 $s 不为 0 的话要先置为 0。
- Fermat618
- 帖子: 728
- 注册时间: 2008-12-28 16:01
Re: 关于块选择的问题
这种用 awk 又快又直接。
这个也就是个怎么把数据读进去的问题,求平均数几乎不是问题。
代码: 全选
awk '{ sum += $2; n += 1 } END { print sum/n }' foo.txt
爱因斯坦会弹钢琴
爱因斯坦会拉小提琴
爱因斯坦会骑自行车
爱因斯坦会拉小提琴
爱因斯坦会骑自行车
- jobinson99
- 帖子: 1169
- 注册时间: 2007-04-28 15:14
- 系统: NixOS+虚拟机各种系统
- 联系:
Re: 关于块选择的问题
统计中经常把数据保存为空格或者tab间隔的文本文件的,这样可以导入到excel或者libreoffice的calc、spss等中,导入后,想计算平均还不是小菜。
黑色的不是眼睛,而是眼圈
关注和实现科技领域未来3年内有大规模普及潜力、能改善穷人生活品质的技术/应用。
NixOS + lxqt + 无人生产线 + 无人农场 (已发明全套山地农业机械 + 线性喷洒系统,成片农业采收系统)+ 随身设备,柔性电路,冷热双调衣……
关注和实现科技领域未来3年内有大规模普及潜力、能改善穷人生活品质的技术/应用。
NixOS + lxqt + 无人生产线 + 无人农场 (已发明全套山地农业机械 + 线性喷洒系统,成片农业采收系统)+ 随身设备,柔性电路,冷热双调衣……
-
- 帖子: 1983
- 注册时间: 2010-05-01 21:23
Re: 关于块选择的问题
我觉得既然文件很多,选择python或者libreoffice的vba是比较好的,都能很好的完成这项任务。
-
- 帖子: 22
- 注册时间: 2012-03-09 18:08
Re: 关于块选择的问题
非常感谢各位,由于时间仓促,没有话更多时间去仔细研究这个问题,这次采用了7楼的方法,感谢 Fermat618 的无私帮助。也感谢其他几位大神的积极相助,日后再来学习。
-
- 帖子: 1453
- 注册时间: 2008-05-24 8:30
Re: 关于块选择的问题
使用 7 楼的方法,小心数据文件中不要有空行,否则平均值会不对。可以略微改一改,避免这种问题。ahgcookie 写了:非常感谢各位,由于时间仓促,没有话更多时间去仔细研究这个问题,这次采用了7楼的方法,感谢 Fermat618 的无私帮助。也感谢其他几位大神的积极相助,日后再来学习。
代码: 全选
awk 'NF==2 { sum += $2; n += 1 } END { print sum/n }' foo.txt
-
- 帖子: 750
- 注册时间: 2006-03-19 11:39
Re: 关于块选择的问题
似乎我有时也会遇到类似问题,一般情况下都是:列拷贝 加括弧和运算符……现在想起来太二了
用脚本的话又不灵活,因为可能选择其它列,或者其它操作
来个 emacs 版本的
[lisp]
(defun thing-on-column (fn &optional n)
(save-excursion
(let ((c (current-column))
(n (if mark-active
(prog1
(count-lines (region-beginning)(region-end))
(goto-char (region-beginning)))
(or n 1)))
lst)
(while (> n 0)
(setq n (1- n))
(move-to-column c)
(setq lst (cons (funcall fn) lst))
(forward-line))
(reverse lst))))
(defun calc-column (fn)
(interactive "aOperation: ")
(message
(number-to-string
(apply fn
(mapcar
'read
(thing-on-column
'current-word))))))
(defun average (&rest lst)
(/ (float (apply '+ lst)) (length lst)))
[/lisp]
区域开始结束位于列的上下两端 ,然后 calc-column ,然后提示操作, average 求平均数……或者 + 求和 * 求积之类的
缺点是需要选择区域,行数比较多的话比较纠结。不过在假设你用 emacs 的情况下,按我上面所说的操作,其实同样需要选择区域
当然也可以不用选择区域,类似楼上的解决方式,用 emacs 同样挺简单,不过感觉那样有点太随便了。我随便起来不是人,但我不是一个随便的人

用脚本的话又不灵活,因为可能选择其它列,或者其它操作
来个 emacs 版本的
[lisp]
(defun thing-on-column (fn &optional n)
(save-excursion
(let ((c (current-column))
(n (if mark-active
(prog1
(count-lines (region-beginning)(region-end))
(goto-char (region-beginning)))
(or n 1)))
lst)
(while (> n 0)
(setq n (1- n))
(move-to-column c)
(setq lst (cons (funcall fn) lst))
(forward-line))
(reverse lst))))
(defun calc-column (fn)
(interactive "aOperation: ")
(message
(number-to-string
(apply fn
(mapcar
'read
(thing-on-column
'current-word))))))
(defun average (&rest lst)
(/ (float (apply '+ lst)) (length lst)))
[/lisp]
区域开始结束位于列的上下两端 ,然后 calc-column ,然后提示操作, average 求平均数……或者 + 求和 * 求积之类的
缺点是需要选择区域,行数比较多的话比较纠结。不过在假设你用 emacs 的情况下,按我上面所说的操作,其实同样需要选择区域
当然也可以不用选择区域,类似楼上的解决方式,用 emacs 同样挺简单,不过感觉那样有点太随便了。我随便起来不是人,但我不是一个随便的人
-
- 帖子: 54
- 注册时间: 2008-03-12 14:33
Re: 关于块选择的问题
操作系统:Linux erocpil 2.6.38-gentoo-r6 #2 SMP Sun Sep 11 10:15:16 GMT 2011 x86_64 Intel(R) Core(TM)2 CPU T5200 @ 1.60GHz GenuineIntel GNU/Linux
编程语言:C/C++,Perl。
谷歌代码:manshow-重新编译的win32版本Vim,加入诸多特性:非等宽中文字体(如微软雅黑),脚本语言接口(如Perl,Python,Lua),透明效果等。
个人主页:http://lyx.us.tc/
编程语言:C/C++,Perl。
谷歌代码:manshow-重新编译的win32版本Vim,加入诸多特性:非等宽中文字体(如微软雅黑),脚本语言接口(如Perl,Python,Lua),透明效果等。
个人主页:http://lyx.us.tc/
- lilydjwg
- 论坛版主
- 帖子: 4258
- 注册时间: 2009-04-11 23:46
- 系统: Arch Linux
- 联系:
Re: 关于块选择的问题
原来 Perl 也支持 END 啊。那 BEGIN 也支持啰?xvii 写了:
-
- 帖子: 403
- 注册时间: 2007-10-27 1:04
Re: 关于块选择的问题
奇怪,我自己实验,好好的啊?能粘贴的。但若用vim选择块则无法直接在Calc中粘贴,
就是没想到小狐狸提供的方法真的很棒。只可惜,自己不会python和perl。累的自己,以前还写了一个vim插件,专门用来处理tsv格式的数据。