Манипуляции с файлами: вопрос сценариев - PullRequest
3 голосов
/ 19 сентября 2010

У меня есть скрипт, который подключается к базе данных и получает все записи, которые подтверждают запрос.Эти результаты записи являются файлами, присутствующими на сервере, поэтому теперь у меня есть текстовый файл, в котором есть все имена файлов.

Мне нужен скрипт, который бы знал:

  1. Что такоеразмер каждого файла в output.txt файле?
  2. Каков общий размер всех файлов, присутствующих в этом текстовом файле?

Обновление: Я хотел бы знать, как я могу достичь своей цели, используя Perl programming language, любые отзывы будут высоко оценены.

Примечание: У меня нет особых языковых ограничений, это может быть язык сценариев Perl или Python, который я могу запустить из командной строки Unix.В настоящее время я использую оболочку bash и у меня есть сценарии 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, и это мой первый раз.

Вот оно:

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.txt, в некоторыеКак найти другое местоположение папки, используя Perl?
  2. После выполнения шага 1, как я могу удалить все файлы, которые присутствуют в файле output.txt?

Любые предложения будут очень благодарны

Ответы [ 4 ]

1 голос
/ 20 сентября 2010

В 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 -s эквивалентно du -b.Вам, вероятно, следует прочитать справочные страницы на вашем конкретном du, чтобы убедиться, что вы действительно измеряете то, что вы собираетесь измерять.

Если вы действительно хотите значения du, измените присвоение на $sizeвыше:

my ($size) = split(' ', `du "$folderpath/$_"`);
1 голос
/ 20 сентября 2010

Глазное яблоко, вы можете заставить СВОЙ сценарий работать следующим образом:

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'. У некоторых файлов есть имена, которые нужно экранировать, но это делается с помощью одинарных кавычек вокруг имени файла.

Это будет запускать du -h для каждого файла в текстовом файле .txt, но не даст вам общее количество. Это довольно просто в 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". Вы также можете обрабатывать несколько файлов.

0 голосов
/ 19 сентября 2010

Вы можете использовать скелет Python, который вы набросали, и добавить os.path.getsize(fullpath), чтобы получить размер отдельного файла.

Например, если вам нужен словарь с именем и размером файла, вы можете:

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

Имейте в виду, что результат os.path.getsize(...) указан в байтах, поэтому вам придется преобразовать его, чтобы получить другие единицы, если хотите.

В целом os.path - это ключевой модуль для работы с файлами и путями.

0 голосов
/ 19 сентября 2010

Вы можете сделать это в самом скрипте.

У вас есть все имена файлов в вашем буферном файле output.txt, все, что вам нужно добавить в конце существующего скрипта:

< output.txt  du -h

Он даст размер каждого файла, а также итоговую сумму в конце.

...