2009-07-13 5 views
-2

Если у меня есть один файл FOO_1.txt, который содержит:Как объединить файлы в один файл CSV?

FOOA 

FOOB 

FOOC 

FOOD 

... 

и много всяких других файлов FOO_files.txt. Каждый из них содержит:

1110000000 ...

одна строка, которая содержит 0 или 1 как число FOO1 значений (fooa, foob ...)

Теперь я хочу, чтобы объединить их один файл FOO_RES.csv, который будет иметь следующий формат:

FOOA,1,0,0,0,0,0,0... 

FOOB,1,0,0,0,0,0,0... 

FOOC,1,0,0,0,1,0,0... 

FOOD,0,0,0,0,0,0,0... 

... 

что такое простой & элегантный способ проведения, что (с hash & массивы -> $ hash {$ key} = \ @data)?

Большое спасибо за помощь!

Yohad

+0

более подробно объясните, как появляются столбцы csv. – ghostdog74

+4

Мое впечатление, основанное на ваших вопросах, заключается в том, что вы взяли на себя работу, о которой вы не знаете, как это сделать. Теперь вы пытаетесь закончить его, заставив нас решить каждый шаг для вас. В процессе обфускации информации, чтобы ваш работодатель/клиент/учитель не мог понять, что вы делаете, вы ставите вопросы в неразборчивые беспорядки. Я был бы очень признателен, если бы кто-нибудь мог объяснить, о чём этот вопрос, или если вы можете прояснить общую картину. В конце концов, помогать другим, которые пытаются помочь вам, будет полезно для вас. –

+0

Кажется, что я единственный ответ на ваш вопрос. Возможно, вам захочется проявить большую признательность тем, кто пытается вам помочь. –

ответ

3

Если вы не можете четко описать свои данные и ваш желаемый результат, вы не сможете его кодировать - принятие простого проекта - это хороший способ начать работу с нового языка.

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

Как написать программу:

  1. Откройте свой текстовый редактор и запишите, какие данные есть. Сделать каждую строку комментария
  2. Опишите желаемые результаты.
  3. Начните описывать шаги, необходимые для изменения ваших данных в нужную форму.

Числа 1 & 2 завершен:

#!/usr/bin perl 
use strict; 
use warnings; 

# Read data from multiple files and combine it into one file. 
# Source files: 
# Field definitions: has a list of field names, one per line. 
# Data files: 
#  * Each data file has a string of digits. 
#  * There is a one-to-one relationship between the digits in the data file and the fields in the field defs file. 
# 
# Results File: 
# * The results file is a CSV file. 
# * Each field will have one row in the CSV file. 
# * The first column will contain the name of the field represented by the row. 
# * Subsequent values in the row will be derived from the data files. 
# * The order of subsequent fields will be based on the order files are read. 
# * However, each column (2-X) must represent the data from one data file. 

Теперь, когда вы знаете, что у вас есть, и где вам нужно идти, вы можете конкретизировать, что программа должна сделать, чтобы получить Вас там - это это шаг 3:

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

# Get a list of fields. 
# Read the field definitions file into an array. 

Поскольку EAS iest для записи CSV в строковой ориентации, вам необходимо обработать все ваши файлы, прежде чем генерировать каждую строку. Таким образом, вам понадобится место для хранения данных.

# Create a variable to store the data structure. 

Теперь мы читаем файлы данных:

# Get a list of data files to parse 
# Iterate over list 

# For each data file: 
# Read the string of digits. 
# Assign each digit to its field. 
# Store data for later use. 

У нас есть все данные в памяти, теперь пишут вывод:

# Write the CSV file. 
# Open a file handle. 

# Iterate over list of fields 
# For each field 
# Get field name and list of values. 
# Create a string - comma separated string with field name and values 
# Write string to file handle 

# close file handle. 

Теперь вы можете начать преобразования комментариев в код. Для каждого комментария может быть от 1 до 100 строк кода. Вы можете обнаружить, что что-то, что вам нужно сделать, очень сложно, и вы не хотите его принимать в данный момент. Создайте фиктивную подпрограмму для обработки сложной задачи и игнорируйте ее, пока не получите все остальное. Теперь вы можете решить эту сложную, тернистую суб-проблему самостоятельно.

Поскольку вы только изучаете Perl, вам нужно нажать на документы, чтобы узнать, как выполнять каждую из подзадач, представленных комментариями, которые вы написали. Лучшим ресурсом для такого рода работ является the list of functions by category in perlfunc. Perl syntax guide тоже пригодится. Поскольку вам нужно будет работать со сложной структурой данных, вы также захотите прочитать с Data Structures Cookbook.

Возможно, вам интересно, как вы должны знать, какие страницы perldoc вы должны читать для данной проблемы. Статья о Perlmonks под названием How to RTFM дает хорошее представление о документации и способах ее использования.

Отличная вещь, если вы застряли, у вас есть код для обмена, когда вы просите о помощи.

+0

почему ты покровительствует ему? Как вы думаете, он даже не знает, как программировать? – hhafez

+0

Hey daotoad, Спасибо! это поможет мне увидеть все более ясно! Хотя я знаю, как программировать, у меня всегда есть новые вещи, чтобы учиться! – YoDar

+1

@hhafez, исходя из его вопросов, у Йохата возникают проблемы с разбивкой его проблем на работоспособные элементы. В дополнение к тому, что он не смог описать свои цели, в трех сообщениях Йохад показал одну строку кода - заявление о печати. Кроме того, вопросы являются основными и могут быть легко найдены в документах. Это указывает на тех, кто нуждается в помощи в основных принципах. Я предложил совет о том, как подойти к проблеме, которая потребовала мне лет, чтобы прийти (да, я такой тупой!). Я также предоставил руководство по огромному предоставлению документов Perl. По моему опыту, внимание к основам - это путь к мастерству. – daotoad

1

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

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

+0

Мои мысли точно. –

0

Вам не нужно использовать хэш. Мой Perl немного ржавый, поэтому синтаксис может быть прочь немного, но в основном это сделать:

open KEYFILE , "foo_1.txt" or die "cannot open foo_1 for writing"; 
open VALFILE , "foo_files.txt" or die "cannot open foo_files for writing"; 
open OUTFILE , ">foo_out.txt"or die "cannot open foo_out for writing"; 

my %output; 
while (<KEYFILE>) { 
    my $key = $_; 
    my $val = <VALFILE>; 
    my $arrVal = split(//,$val); 

    $output{$key} = $arrVal; 
    print OUTFILE $key."," . join(",", $arrVal) 
} 

Edit: флажок Синтаксис OK

Комментарий Синан: @Byron, так ли действительно беспокоит меня, что ваше первое предложение говорит, что OP не нуждается в хэше, но ваш код имеет %output, который, кажется, не имеет никакой цели. Для справки, ниже приведен менее верный способ сделать то же самое.

#!/usr/bin/perl 

use strict; 
use warnings; 

use autodie qw(:file :io); 

open my $KEYFILE, '<', "foo_1.txt"; 
open my $VALFILE, '<', "foo_files.txt"; 
open my $OUTFILE, '>', "foo_out.txt"; 

while (my $key = <$KEYFILE>) { 
    chomp $key; 
    print $OUTFILE join(q{,}, $key, split //, <$VALFILE>), "\n"; 
} 
__END__ 
+0

@Byron: Ваш код не будет компилироваться, и он не делает то, что вы думаете. В вызовах «открыть» есть недостающие запятые, и без спецификации 'open' всегда открывается файл для чтения. Итак, ни один из них не является файловыми дескрипторами для _writing_. – Telemachus

+0

Как я уже сказал, мой perl ржавый, я только пытался рассказать об алгоритме. Если читатель не может понять, как это сделать, я думаю, что исходный комментарий Синана прав, плакат находится над головой. –

+0

@Byron и @Telemachus Я попытался изменить код Байрона, но потом решил, что слишком сильно меняю и откатываю назад. –

1

Ваши технические требования не ясны. У вас не могло быть «большого количества других файлов» с именемFOO_files.txt, потому что это только одно имя. Поэтому я собираюсь использовать это как шаблон с файлами с данными + filelist. В этом случае есть файлы с именем FOO*.txt, каждый из которых содержит «[01] + \ n".

Таким образом, идея состоит в том, чтобы обрабатывать все файлы в файле списка файлов и вставлять их все в файл результатов, разделенный запятой.

use strict; 
use warnings; 
use English qw<$OS_ERROR>; 
use IO::Handle; 

open my $foos, '<', 'FOO_1.txt' 
    or die "I'm dead: $OS_ERROR"; 
@ARGV = sort map { chomp; "$_.txt" } <$foos>; 
$foos->close; 

open my $foo_csv, '>', 'FOO_RES.csv' 
    or die "I'm dead: $OS_ERROR"; 

while (my $line = <>) { 
    my ($foo_name) = ($ARGV =~ /(.*)\.txt$/); 
    $foo_csv->print(join(',', $foo_name, split //, $line), "\n"); 
} 

$foo_csv->close; 
+0

Я не уверен, почему 'use English;' считается улучшением. –

+0

Я не уверен, почему вы думаете, что это единственное, что отличается от моего предложения. – Axeman

+0

@Axeman Я бы не поддержал ваш ответ, если бы подумал. Обратите внимание, что в моем комментарии используется пассивный голос: похоже, довольно много людей, которые считают, что '$ OS_ERROR' лучше, чем' $! '. Я не согласен. Это все. Кстати, я использовал бы «File :: Slurp» для первой части: '@ARGV = сортировать карту {chomp; «$ _. txt»} read_file 'FOO_1.txt'; ' –

1

Похоже, у вас есть много foo_files, которые имеют 1 строку в них, что-то вроде:

1110000000 

Что стоит за

fooa=1 
foob=1 
fooc=1 
food=0 
fooe=0 
foof=0 
foog=0 
fooh=0 
fooi=0 
fooj=0 

И это выглядит как ваш foo_res это просто суммирование этих значений? В этом случае вам не нужен хэш массивов, а просто хэш.

Это довольно сложно понять, о чем вы просите, но, может быть, это помогает?

Смежные вопросы