文件操作:脚本问题

时间:2010-09-19 16:43:22

标签: python perl file unix scripting

我有一个连接到数据库的脚本,并获取满足查询的所有记录。这些记录结果是服务器上的文件,所以现在我有一个文本文件,其中包含所有文件名。

我想要一个知道的脚本:

  1. output.txt文件中每个文件的大小是多少?
  2. 该文本文件中存在的所有文件的总大小是多少?
  3. 更新 我想知道如何使用Perl programming language完成任务,任何输入都将受到高度赞赏。

    注意:我没有任何特定的语言限制,它可以是Perl或Python脚本语言,我可以从Unix提示符运行。目前我正在使用bash shell并拥有shpy脚本。怎么办呢?

    我的脚本:

    #!/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

    任何指导都将受到高度赞赏。

    更新

    1. 如何使用output.txtPerl文件中的所有文件移动到其他文件夹位置?
    2. 执行step1后,如何删除output.txt文件中的所有文件?
    3. 任何建议都将受到高度赞赏。

4 个答案:

答案 0 :(得分:1)

眼球,你可以让你的脚本以这种方式工作:

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相同的方式。如果我针对我在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)

然后,您可以通过chmod +x [script_name].py执行脚本(在./script.py ft.txt之后),然后它将使用命令行文件的路径作为文件“ft.txt”的假定路径。您也可以处理多个文件。

答案 1 :(得分:1)

在perl中,-s filetest运算符可能是你想要的。

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上的手册页,以确保您实际测量的是您想要测量的内容。

如果您确实需要du值,请将上面的$size分配更改为:

my ($size) = split(' ', `du "$folderpath/$_"`);

答案 2 :(得分:0)

您可以在自己的shell脚本中执行此操作。

您的假脱机文件output.txt中包含所有文件名,您必须在现有脚本的末尾添加所有文件名:

< output.txt  du -h

它将给出每个文件的大小以及最后的总数。

答案 3 :(得分:0)

您可以使用已勾画出的Python骨架并添加os.path.getsize(fullpath)以获取单个文件的大小。

例如,如果您想要一个包含文件名和大小的字典,您可以:

dict((f, os.path.getsize(f)) for f in file)

请注意,os.path.getsize(...)的结果以字节为单位,因此如果需要,您必须将其转换为其他单位。

通常os.path是操作文件和路径的关键模块。