开发者

How can I replace a column of one file with a column of another using Perl?

Suppose File 1 has two columns and looks something like:

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开发者_JAVA技巧 light particle

File 2 has only one clumn and looks something like:

azalea
azure
Byzantine
Czech
dyslexic
dyspeptic
eyrie
fuzz

I want the first column of File 1 replaced with the column of File 2. Thus, File 3 should look like this:

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

I have a feeling that there's one or another simple way of doing this kind of job and it is very likely that ther're some handy modules out there but for now I simply can't do it even in the most inefficient way. I tried a bunch of code like

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

but no luck at all. Can someone kindly point me in the right direction? Thanks, as always, for any guidance.


If you want to read two lines at the same time, try this:

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

This will stop working as soon as one line runs out, so it may be a good idea to see if both files are empty at the end of this loop:

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

Of course, in modern Perl you can store filehandles in lexically scoped variables like this:

open my $fh, ...

And then replace ugly global <FILEHANDLES> with nice lexically scoped <$filehandles>. It's much nicer, and it makes


I read this as you want to output the first file sorted like the second. After rereading it It seems you just want to replace the column, without changing order. Here's the solution to that assuming you can handle opening the files.

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

Here's my original solution, to sort the entries in the order they appear in the second file.

Create a hash of file 1.

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

Look up the definition for each key in file 2 and print a joined line

while (<FILE2>){     
  $key =~ s/\s*//g;
  print FILE3 "$key\t\t$dictionary{$key}\n";
}


Think about what you want to do, in small steps.

  • read in one line from each file.
  • File 1 has two columns, so split it into two columns.
  • now you have one line from File 1 (in two parts), and a line from File 2.
  • print the parts you want to keep: the first part of File 1, and the part from File 2.

And then you keep doing that until you run out of lines from one file or the other.

Here's some of the pieces you need:

  • open a file: open(my $filehandle, '<', 'filename') or die "Can't open filename";
  • read a single line: my $line = <$filehandle>;
  • split it into two columns: there's lots of ways of doing this - with a regexp, or split(), or even substr()
  • print a line out: pretty simple
  • if you run out of lines, you're done: exit if !$line;


You can use " cut -c 10- file1 | paste file2 - " on *nix.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜