2010-12-29 7 views
0

두 개의 입력 파일을 읽고 각 입력 파일의 해당 줄을 연결 한 한 줄을 포함하는 새 파일을 출력하려고합니다. 예를 들어Perl에서 두 파일을 결합하는 방법은 무엇입니까?

: 새로운 출력 파일의

라인 1 것이다 :

info from input file 1, line 1 some number of tabs info from input file 2, line 1 
. 
. 
. 

를 하나 입력 파일 라인의 나머지는 출력 파일에 삽입해야 다른 것보다 더 라인이있는 경우 그들의 정확한 위치에.

감사합니다.

+2

어떤 연구? – bzlm

+3

당신은 * NIX 시스템에 있습니까? 'perl -e 'exec @ARGV'paste/tmp/file1/tmp/file2' :) – pilcrow

+0

@pilcrow : 예. * NIX에 있는데 솔루션이 잘 작동했습니다. 나는 나 자신을 생각해 내지 못했다고 나는 믿을 수 없다. 게시하기 전에 조사를했지만 붙여 넣기 명령을 고려하는 것을 잊었습니다. 감사. –

답변

1
open FP1,"filename1"; 
open FP2,"filename2"; 
my ($l1,$l2); 
while(1) 
{ 
    $l1=<FP1>; chomp $l1; 
    $l2=<FP2>; chomp $l2; 
    last unless(defined $l1 or defined $l2); 
    print $l1.$l2,"\n"; 
} 
close FP2; 
close FP1; 
+0

감사합니다. 이것은 매우 도움이되었습니다. –

+8

베어 메 (bareword) 파일 핸들을 사용하는 예제 코드 나 open의 2 arg 형식을 제공하지 말거나 open 반환을 무시하십시오. 모두는 매우 실망스러운 관행입니다. –

+2

@ Ven'Tatsu : ... 엄격한 사용 경고를 사용하지 않았습니다. 그리고 파일을 열 수없는 경우를 처리하지 않았습니다. bla, bla, bla, .... 누군가의 취향을 만족시키지 못하기 때문에 항상 펄 스크립트에 대해 할 수있는 수천 가지의 것들이 있습니다. 제발 그렇게 까다 롭지 마세요! – Curd

0

어떤 파일에 더 많은 줄이 있는지 먼저 쿼리 할 수 ​​있습니다 (wc -l). (의사의 이익을 위해) 가정하면 그 파일 1 개 라인을 가지고, 다음을 수행하십시오

use strict; 
use warnings; 

open(my $fh,"<","file 1") or die ("Couldn't open file 1: $!"); 
open(my $write,">","output.csv") or die ("Couldn't open output.csv: $!"); 

my $str; 
my $count=1; 

while(my $line=<$fh>) 
{ 
    $str=`head -n $count file 2 | tail -n 1`. (\tx[however many tabs you want]) . $line; 
    print $write $str; 
    $count++; 
} 

close($fh); 
close($write); 
+0

감사합니다. 이것은 매우 도움이되었습니다. –

+0

반갑습니다. 나는 $ str의 첫 부분을 끝냈다. (''echo -n $ count file 2''를 사용하면 원하는 것을 얻을 수 없다.) 나는 그것을 고쳤다. –

1

이 정말 차이가 없습니다와 당신이 펄의 트릭의 몇 가지에주의로 하나 개의 파일을 통해 반복. 한 파일의 경우는 모두를 열고 두 파일이 읽기 수행에만 끝에 조건부 루프를 변경하여

use strict; 
use warnings; 
use English qw(-no_match_vars); 

my $filename = 'foo'; 
open my $file, '<', $filename or die "Failed to open '$filename' $OS_ERROR\n"; 

while (my $line = <$file>) { 
    # work with $line 
} 

close $file; 

이 두 파일을 확장 할 수 있습니다를 사용하는 것이 일반적이다. 하지만 catch가 있습니다. Perl은 while 루프의 조건부로 파일 핸들에서 간단한 읽기를 보았을 때 defined()에 랩핑합니다. 왜냐하면 조건부는 단순한 읽기 이상이므로 수동으로 수행해야하기 때문입니다.

use strict; 
use warnings; 
use English qw(-no_match_vars); 

my $filename1 = 'foo'; 
my $filename2 = 'bar'; 
open my $file1, '<', $filename1 or die "Failed to open '$filename1' $OS_ERROR\n"; 
open my $file2, '<', $filename2 or die "Failed to open '$filename2' $OS_ERROR\n"; 

my ($line1, $line2); 
while (do { $line1 = <$file1>; $line2 = <$file2>; defined($line1) || defined($line2) }) { 
    # do what you need to with $line1 and $line2 
} 

close $file1; 
close $file2; 
+0

매우 흥미 롭습니다. 그러나 한 파일의 행 수가 다른 행보다 적 으면이 루프는 두 파일의 모든 행을 통과하기 전에 중지하지 않습니까? –

+1

Nope. 예를 들어, 파일 1에 100 개의 행이 있고 파일 2에 90 개의 행이 있으면 $ line2는 처음 90 개의 반복에 대해서만 정의되고 $ line1은 모든 100 개의 반복에 대해 정의됩니다. 그러나 "or"(즉, ||)은 100 개의 반복을 반복합니다. –

+1

두 개의 열린 문 '>'은 '<'이어야합니다. 두 파일은 출력 파일이 아닌 입력 파일입니다. 실수로 파일의 데이터를 날려 버리는 좋은 방법입니다. –

1

나는 물건을 집계하기위한 해시를 좋아합니다. 이것은 특히 우아하지는 않지만 빠르다. 당신이 할 않았다, 당신은 붙어 어디에서 얻었 는가

#!perl 
use strict; 
use warnings; 

my ($file1, $file2) = @ARGV; 
die "usage: $0 file1 file2\n" 
    unless $file1 && $file2; 

use File::Slurp; 
my @a = read_file($file1) 
    or die "couldn't read $file1 - $!"; 
my @b = read_file($file2) 
    or die "couldn't read $file2 - $!"; 

my $combined = {}; # hashref 

my $i=0; 
foreach (@a) { 
    chomp; 
    $combined->{$i}{b} = '' unless defined $combined->{$i}{b}; 
    $combined->{$i++}{a} = $_; 
} 

$i=0; 
foreach (@b) { 
    chomp; 
    $combined->{$i}{a} = '' unless defined $combined->{$i}{a}; 
    $combined->{$i++}{b} = $_; 
} 

foreach my $i (sort {$a<=>$b} keys %$combined) { 
    print $combined->{$i}{a}, ("\t" x 2), $combined->{$i}{b}, "\n"; 
} 
+0

네, 매우 우아하고 훌륭합니다. 예를 들어 솔루션을 구현하기 위해 해시를 적용한 경우 고마워요. –

+0

글쎄, 고마워요, 아니면 환영하겠습니다. @Horace – Nathan

+0

이제 생각해 봅시다. 해시 배열은 b 일 수 있습니다. 해시의 해시보다 더 낫습니다. 열쇠를 정렬하는 것을 망칠 필요는 없습니다. 내내'{$ i}'를'[$ i]'로 변경하십시오. 원래 길이가 다른 파일을 처리하기 위해 해시를 생각했습니다. – Nathan

0
#!/usr/bin/env perl 

#merging 3 - lines of first file and 3 lines of second file and next of these. 
open(F1, "<file1") or die "\ncould not find your file1\n"; 

[email protected];@lines1 = <F1> ; 

close(F1); 

open(F2, "<file2") or die "\ncould not find your file2\n"; 

[email protected];@lines2 = <F2> ; 

close(F2); 

my $value; 
my $nums; 

print "\nplease write your output file name::::\n"; 

chomp($file = <STDIN>); 

open(F3, "> $file") or die "\n could not write into your file\n"; 

$value = 0; 
foreach $nums(@lines1) { 


    if ($value % 3 == 0) { 

     print F3 $lines2[$value]; 
     print F3 $lines2[$value + 1]; 
     print F3 $lines2[$value + 2]; 

    } 
    print F3 $nums; 
    $value++; 

} 
close(F3); 
관련 문제