我有一个脚本连接到数据库,并获取所有logging统计查询。 这些logging结果是服务器上的文件,所以现在我有一个文本文件,其中包含所有的文件名。
我想要一个脚本,知道:
output.txt
文件中每个文件的大小是多less? 更新:我想知道如何使用Perl programming language
来实现我的任务,任何input将不胜感激。
注意:我没有任何特定的语言限制,可以是Perl或Python脚本语言,我可以从Unix提示符运行。 目前我正在使用bash shell,并有sh
和py
脚本。 如何才能做到这一点?
我的脚本:
#!/usr/bin/ksh export ORACLE_HOME=database specific details export PATH=$ORACLE_HOME/bin:path information sqlplus database server information<<EOF SET HEADING OFF SET ECHO OFF SET PAGESIZE 0 SET LINESIZE 1000 SPOOL output.txt select * from my table_name; SPOOL OFF EOF
我知道du -h
将是我应该使用的命令,但是我不知道我的脚本应该如何,我已经在python中尝试了一些东西。 我对Python完全陌生,这是我第一次努力。
这里是:
import os folderpath='folder_path' file=open('output file which has all listing of query result','r') for line in file: filename=line.strip() filename=filename.replace(' ', '\ ') fullpath=folderpath+filename # print (fullpath) os.system('du -h '+fullpath)
输出文本文件中的文件名例如: 007_009_Bond Is Here_009_Yippie.doc
任何指导将不胜感激。
更新:
output.txt
文件中存在的所有文件移动到使用Perl
其他文件夹位置? 任何build议将不胜感激。
在perl中, -s
filetest操作符是probaby你想要的。
use strict; use warnings; use File::Copy; my $folderpath = 'the_path'; my $destination = 'path/to/destination/directory'; open my $IN, '<', 'path/to/infile'; my $total; while (<$IN>) { chomp; my $size = -s "$folderpath/$_"; print "$_ => $size\n"; $total += $size; move("$folderpath/$_", "$destination/$_") or die "Error when moving: $!"; } print "Total => $total\n";
请注意, -s
以字节为单位给出大小不是像du
这样的块 。
在进一步的调查中,perl的-s
相当于du -b
。 你可能应该阅读你的具体文件的手册页,以确保你正在测量你打算测量的内容。
如果您确实需要du
值,请将分配更改为$size
以上:
my ($size) = split(' ', `du "$folderpath/$_"`);
目光,你可以使你的脚本这样工作:
1)删除行filename=filename.replace(' ', '\ ')
转义比这更复杂,你应该引用完整的路径或使用Python库来逃避它基于特定的操作系统;
2)您可能在路径和文件名之间缺少分隔符;
3)在调用os.system的时候,你需要在完整路径中使用单引号。
这适用于我:
#!/usr/bin/python import os folderpath='/Users/andrew/bin' file=open('ft.txt','r') for line in file: filename=line.strip() fullpath=folderpath+"/"+filename os.system('du -h '+"'"+fullpath+"'")
文件“ft.txt”有没有路径的文件名,路径部分是'/Users/andrew/bin'
。 有些文件的名字需要被转义,但是文件名称周围的单引号需要注意。
这将在.txt文件中的每个文件上运行du -h
,但是不会给你总数。 在Perl或Python中这相当简单。
这里是一个Python脚本(基于你的)来做到这一点:
#!/usr/bin/python import os folderpath='/Users/andrew/bin/testdir' file=open('/Users/andrew/bin/testdir/ft.txt','r') blocks=0 i=0 template='%d total files in %d blocks using %d KB\n' for line in file: i+=1 filename=line.strip() fullpath=folderpath+"/"+filename if(os.path.exists(fullpath)): info=os.stat(fullpath) blocks+=info.st_blocks print `info.st_blocks`+"\t"+fullpath else: print '"'+fullpath+"'"+" not found" print `blocks`+"\tTotal" print " "+template % (i,blocks,blocks*512/1024)
请注意,这次您不必引用或转义文件名; Python为你做。 这使用分配块计算文件大小; 杜相同的方式。 如果我运行du -ahc
对付我在ft.txt
列出的相同文件,我会得到相同的编号(好吧, du
报告它为25M
,我得到的报告为24324 KB
),但报告的块数相同。 (注意:即使在较大的光盘上实际的块大小总是较大,在Unix下,“块”总是被认为是512字节。)
最后,您可能需要考虑制作脚本,以便它可以读取一组命令行文件,而不是对脚本中的文件和路径进行硬编码。 考虑:
#!/usr/bin/python import os, sys total_blocks=0 total_files=0 template='%d total files in %d blocks using %d KB\n' print for arg in sys.argv[1:]: print "processing: "+arg blocks=0 i=0 file=open(arg,'r') for line in file: abspath=os.path.abspath(arg) folderpath=os.path.dirname(abspath) i+=1 filename=line.strip() fullpath=folderpath+"/"+filename if(os.path.exists(fullpath)): info=os.stat(fullpath) blocks+=info.st_blocks print `info.st_blocks`+"\t"+fullpath else: print '"'+fullpath+"'"+" not found" print "\t"+template % (i,blocks,blocks*512/1024) total_blocks+=blocks total_files+=i print template % (total_files,total_blocks,total_blocks*512/1024)
然后,您可以通过./script.py ft.txt
执行脚本(在chmod +x [script_name].py
),然后使用命令行文件路径作为文件“ft.txt”的假定路径。 您也可以处理多个文件。
你可以在你的shell脚本中完成它。
您的假脱机文件output.txt
包含所有文件名,您必须在现有脚本末尾添加所有文件名:
< output.txt du -h
它会给每个文件的大小,并在最后总计。
您可以使用您已经勾画出的Python框架,并添加os.path.getsize(fullpath)
来获取单个文件的大小。
例如,如果你想要一个文件名和大小的字典,你可以:
dict((f, os.path.getsize(f)) for f in file)
请记住, os.path.getsize(...)
的结果是以字节为单位的,所以如果需要,你必须将它转换成其他单位。
通常os.path
是处理文件和路径的关键模块。