Как я могу заменить столбец одного файла на столбец другого, используя Perl? - PullRequest
0 голосов
/ 23 октября 2009

Предположим, файл 1 имеет два столбца и выглядит примерно так:

fuzz          n.  flowering shrub of the rhododendron family
dyspeptic     adj. bright blue, as of the sky 
dysplexi      adj. of Byzantium or the E Roman Empire
eyrie         adj. of the Czech Republic or Bohemia
azalea        adj. suffering from dyslexia
Czech         adj. suffering from dyspepsia
Byzantine     n. eagle's nest
azure         n. mass of soft light particle

Файл 2 имеет только одну колонку и выглядит примерно так:

azalea
azure
Byzantine
Czech
dyslexic
dyspeptic
eyrie
fuzz

Я хочу, чтобы первый столбец файла 1 был заменен столбцом файла 2. Таким образом, файл 3 должен выглядеть следующим образом:

azalea        n.  flowering shrub of the rhododendron family
azure         adj. bright blue, as of the sky 
Byzantine     adj. of Byzantium or the E Roman Empire
Czech         adj. of the Czech Republic or Bohemia
dyslexic      adj. suffering from dyslexia
dyspeptic     adj. suffering from dyspepsia
eyrie         n. eagle's nest
fuzz          n. mass of soft light particle

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

while<$line1 = file1>{
while<$line2 = file2>{
join $line,$line2 

но не повезло вообще. Может ли кто-нибудь указать мне правильное направление? Спасибо, как всегда, за любые указания.

Ответы [ 4 ]

6 голосов
/ 23 октября 2009

Если вы хотите прочитать две строки одновременно, попробуйте следующее:

while(defined(my $line1 = <file1>)
      and defined(my $line2 = <file2>)) {
  # replace contents in $line1 with $line2 and do something with $line1
}

Это перестанет работать, как только закончится одна строка, поэтому было бы неплохо увидеть, если оба файла пусты в конце этого цикла:

die "Files are different sizes!\n" unless eof(file1) == eof(file2);

Конечно, в современном Perl вы можете хранить дескрипторы файлов в переменных с лексической областью, например:

open my $fh, ...

А затем замените уродливый глобальный <FILEHANDLES> на красивый лексически ограниченный <$filehandles>. Это намного лучше, и это делает

4 голосов
/ 23 октября 2009

Подумайте о том, что вы хотите сделать, маленькими шагами.

  • читать по одной строке из каждого файла.
  • Файл 1 имеет два столбца, поэтому разбейте его на два столбца.
  • теперь у вас есть одна строка из файла 1 (из двух частей) и строка из файла 2.
  • напечатайте части, которые вы хотите сохранить: первую часть файла 1, а часть из файла 2.

И затем вы продолжаете делать это, пока у вас не закончатся строки из одного или другого файла.

Вот некоторые кусочки, которые вам нужны:

  • открыть файл: open(my $filehandle, '<', 'filename') or die "Can't open filename";
  • читать одну строку: my $line = <$filehandle>;
  • разделите его на две колонки: есть много способов сделать это - с помощью регулярного выражения, или split(), или даже substr()
  • вывести строку: довольно просто
  • если у вас закончились строки, все готово: exit if !$line;
4 голосов
/ 23 октября 2009

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

while(($line1 = <FILE1>) && ($line2 =  <FILE2>)){
  chomp $line2;
  $line1 =~ s/^\w+/$line2/;
  print FILE3 $line1;
}

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

Создать хеш файла 1.

$dictionary = {}
while (<FILE1>){
  m/^(\w+)\s+(.*)$/;
  $dictionary{$1}=$2;
}

Найдите определение для каждого ключа в файле 2 и напечатайте объединенную строку

while (<FILE2>){     
  $key =~ s/\s*//g;
  print FILE3 "$key\t\t$dictionary{$key}\n";
}
0 голосов
/ 23 октября 2009

Вы можете использовать «cut -c 10- file1 | paste file2 -» для * nix.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...