@tangoa = ('A','B','C','D','E','F');
@tangob = ('K','L','M','N','O','P');
の2つの配列の各要素を結合させて
AK AL AM AN AO AP BK BL BM BN BO BP CK CL CM CN CO CP DK DL DM DN DO DP EK EL EM EN EO EP FK FL FM FN FO FPという配列(@tangoc)を作りたいのですが、
2つの配列の各要素を結合させるにはmapを用いてどのように書くべきか具体的に教えてください。
カレントディレクトリにディレクトリaaa, bbb, cccが在り、さらにそれぞれのディレクトリに11_2とか9_20などのような1から20までの数字を_で2個つなげたディレクトリが在ります。そのディレクトリの中のファイル名を出力する以下のスクリプトgetname.plを作成したのですが、
Unrecognized escape \d passed through at ./getname.pl line 9.
Unrecognized escape \d passed through at ./getname.pl line 9.
というエラーが出ます。全く原因がわからないでいます。もしよろしければ解決法をご教示いただけないでしょうか。どうぞよろしくお願いします。
#!/usr/bin/perl
use strict;
use warnings;
my @directory=qw/aaa bbb ccc/;
foreach my $dname (@directory)
{
opendir(DIR,"./$dname/\d+_\d+");
my @dir=readdir(DIR);
close(DIR);
print join("\n",@dir);
}
print "\n";
【データ】
(A)
A A2 "one" 7
A 3C three 9
B DD "two" 11
C CDE four 25
C 4D five 33
D YY six 27
・
・
(B)
A okinawa kagoshima miyazaki
B kumamoto oita
D fukuoka
E saga nagasaki
・
(A)と(B)のデータを比較し、先頭の単語が一致した時のみ、先頭の単語を除いた(B)の行を
(A)の末尾に加えるという処理をしたいです。
【目標】
A A2 "one" 7 okinawa kagoshima miyazaki
A 3C three 9 okinawa kagoshima miyazaki
B DD "two" 11 kumamoto oita
C CDE four 25
C 4D five 33
D YY six 27 fukuoka
・
・
以前、回答して頂いた方法を踏まえ、以下の処理を行いましたが上記のような結果がでません。
宜しくお願いします。
#!/usr/bin/perl
open(FILE1, "<aaa.txt") || die "File1 Open Error! \n";
open(FILE2, "<bbb.txt") || die "File2 Open Error! \n";
open(OUT, ">zzz.txt") || die "OUT Open Error! \n";
my @data1 = <FILE1>;
my @data2 = <FILE2>;
chomp @data1;
chomp @data2;
foreach my $line1 (@data1) {
my @array1 = split(/\t/, $line1);
push @{$hash1{$array1[0]}}, @array1[1, -1];
for my $key1 (sort keys %hash1){
foreach my $line2 (@data2) {
my @array2 = split(/\t/, $line2);
push @{$hash2{$array2[0]}}, @array2[1, -1];
for my $key2 (sort keys %hash2){
if($key1 eq $key2){
print OUT join("\t", ($key2, @{$hash2{$key2}}, @{$hash1{$key1}})), "\n";
}
}
}
}
}
【データ】
(A)
A A2 "one" 7
A 3C three 9
B DD "two" 11
C CDE four 25
C 4D five 33
D YY six 27
・
・
(B)
A okinawa kagoshima miyazaki
B kumamoto oita
D fukuoka
E saga nagasaki
・
(A)と(B)のデータを比較し、先頭の単語が一致した時のみ、先頭の単語を除いた(B)の行を
(A)の末尾に加えるという処理をしたいです。
【目標】
A A2 "one" 7 okinawa kagoshima miyazaki
A 3C three 9 okinawa kagoshima miyazaki
B DD "two" 11 kumamoto oita
C CDE four 25
C 4D five 33
D YY six 27 fukuoka
・
・
以前、回答して頂いた方法を踏まえ、以下の処理を行いましたが上記のような結果がでません。
宜しくお願いします。
#!/usr/bin/perl
open(FILE1, "<aaa.txt") || die "File1 Open Error! \n";
open(FILE2, "<bbb.txt") || die "File2 Open Error! \n";
open(OUT, ">zzz.txt") || die "OUT Open Error! \n";
my @data1 = <FILE1>;
my @data2 = <FILE2>;
chomp @data1;
chomp @data2;
foreach my $line1 (@data1) {
my @array1 = split(/\t/, $line1);
push @{$hash1{$array1[0]}}, @array1[1, -1];
for my $key1 (sort keys %hash1){
foreach my $line2 (@data2) {
my @array2 = split(/\t/, $line2);
push @{$hash2{$array2[0]}}, @array2[1, -1];
for my $key2 (sort keys %hash2){
if($key1 eq $key2){
print OUT join("\t", ($key2, @{$hash2{$key2}}, @{$hash1{$key1}})), "\n";
}
}
}
}
}
【データ】
(A)
A A2 "one" 7
A 3C three 9
B DD "two" 11
C CDE four 25
C 4D five 33
D YY six 27
・
・
(B)
A okinawa kagoshima miyazaki
B kumamoto oita
D fukuoka
E saga nagasaki
・
(A)と(B)のデータを比較し、先頭の単語が一致した時のみ、先頭の単語を除いた(B)の行を
(A)の末尾に加えるという処理をしたいです。
【目標】
A A2 "one" 7 okinawa kagoshima miyazaki
A 3C three 9 okinawa kagoshima miyazaki
B DD "two" 11 kumamoto oita
C CDE four 25
C 4D five 33
D YY six 27 fukuoka
・
・
以前、回答して頂いた方法を踏まえ、以下の処理を行いましたが上記のような結果がでません。
宜しくお願いします。
#!/usr/bin/perl
open(FILE1, "<aaa.txt") || die "File1 Open Error! \n";
open(FILE2, "<bbb.txt") || die "File2 Open Error! \n";
open(OUT, ">zzz.txt") || die "OUT Open Error! \n";
my @data1 = <FILE1>;
my @data2 = <FILE2>;
chomp @data1;
chomp @data2;
foreach my $line1 (@data1) {
my @array1 = split(/\t/, $line1);
push @{$hash1{$array1[0]}}, @array1[1, -1];
for my $key1 (sort keys %hash1){
foreach my $line2 (@data2) {
my @array2 = split(/\t/, $line2);
push @{$hash2{$array2[0]}}, @array2[1, -1];
for my $key2 (sort keys %hash2){
if($key1 eq $key2){
print OUT join("\t", ($key2, @{$hash2{$key2}}, @{$hash1{$key1}})), "\n";
}
}
}
}
}
perl初心者です。いつもありがとうございます。
perlでcsvファイル(1行のカラム数は200)、総行数は約3万行のファイルを37番目のカラム(-25以上25未満の数値データ)で降順ソートしその値によって行数がだいたい均等になるよう3分割し、2番目のカラムに文字でも数字でもよいのですがその4つのグループごとにフラグ(例えば1,2,3)を入れたいと思ってます。グループ化については境目の37番カラムの値は重複している場合が多いと思うのですがその場合は下(別に上でもかまいません)に入れるものとします。
ソートロジックは過去の質問を参照して理解しましたがグループ化しフラグを入れるルーチンがうまく作れません。下記のように作ったのですがこの先同じことを何度もやらなくてはならないので先に進めません。どなたかお助けください。最終的にやりたいことはカラム37でグループ化→カラム2にフラグを立てる、次にカラム2とカラム38(-25から0までの数値)でソートし同様に同じ行数になるようにグループ化→カラム3にフラグを立てる、さらにカラム2とカラム3とカラム39(-25以上25未満の数値データ)でソートし・・・同様に繰り返し最終的に1グループが100件(行)~150件(行)になるようにしたいのです。つまり約3万件のデータを3*4*2*4*2=192分割(5列の値で分類)したい、そしてどのような範囲で分割したかという情報も得たいのです。
use strict;
use warnings;
use utf8;
use Encode;
binmode STDOUT, ':encoding(utf-8)';
my $dir = './data'; # 処理するディレクトリ
my $motoFile = 'customer.txt'; # もとファイル
open my $fh, '<:encoding(cp932)', "$dir/$motoFile" or die 'ファイルが開けません。',"$!";
my %sorted;
while (my $line = <$fh>) {
my $key = (split /,/, $line)[37];
push @{$sorted{$key}}, $line;
if (@{$sorted{$key}} == 1000) {
open OUT, '>>:encoding(cp932)', "$dir/$key.tmp" or die "Can't open: $!";
print OUT @{$sorted{$key}};
close OUT;
@{$sorted{$key}} = ();
}
}
open OUT, '>:encoding(cp932)', "$dir/out.txt" or die "Can't open: $!";
foreach my $key (sort { $b <=> $a } keys %sorted) {
if (-e "$key.tmp") {
open IN, '<:encoding(cp932)', "$dir/$key.tmp" or die "Can't open: $!";
print OUT while <IN>;
close IN;
}
print OUT @{$sorted{$key}} if @{$sorted{$key}};
}
close OUT;
#↓↓↓↓ここからフラグを作成するルーチン
# 行数を調べ3つに分けるルーチン
my @colum37;
open IN, '<:encoding(cp932)', "$dir/out.txt" or die 'ファイルが開けません。',"$!";
my @in = <IN>;
close IN;
my $gyousuu = scalar(@in);
my $amari = $gyousuu % 3;
if ($amari == 0) {
my $groupGyousuu = ($gyousuu-$amari)/3;
print "総行数は$gyousuu","で、1グループの行数は$groupGyousuu","ほど、余りは$amari\n";
# あまりが0の時、group1は@inの0行 ~$groupGyousuu-1行まで
# group2は@inの$groupGyousuu行 ~$groupGyousuu*2-1行まで
# group3は@inの$groupGyousuu*2行~$groupGyousuu*3-1行まで
foreach my $num (1..2) {
push @colum37, (split /,/, $in[$groupGyousuu*$num])[37]; # これは境目の先頭の37番目
}
print "@colum37\n"; #これでここまでは完成、分けるべき値がこの配列に入っている。
open OUT, '>:encoding(cp932)', "$dir/out.txt" or die "Can't open: $!";
foreach my $line (@in) {
my @line = split /,/,$line;
if ($line[37]>=$colum37[0]) {
$line[1] = 1;
}elsif ($line[37]>=$colum37[1] and $line[37]<$colum37[0]) {
$line[1] = 2;
}elsif ($line[37]<$colum37[1]) {
$line[1] = 3;
}
$line = join (',',@line);
print OUT $line;
}
close OUT;
}
elsif ($amari == 1) { この後未作成
perl初心者です。いつもありがとうございます。
perlでcsvファイル(1行のカラム数は200)、総行数は約3万行のファイルを37番目のカラム(-25以上25未満の数値データ)で降順ソートしその値によって行数がだいたい均等になるよう3分割し、2番目のカラムに文字でも数字でもよいのですがその4つのグループごとにフラグ(例えば1,2,3)を入れたいと思ってます。グループ化については境目の37番カラムの値は重複している場合が多いと思うのですがその場合は下(別に上でもかまいません)に入れるものとします。
ソートロジックは過去の質問を参照して理解しましたがグループ化しフラグを入れるルーチンがうまく作れません。下記のように作ったのですがこの先同じことを何度もやらなくてはならないので先に進めません。どなたかお助けください。最終的にやりたいことはカラム37でグループ化→カラム2にフラグを立てる、次にカラム2とカラム38(-25から0までの数値)でソートし同様に同じ行数になるようにグループ化→カラム3にフラグを立てる、さらにカラム2とカラム3とカラム39(-25以上25未満の数値データ)でソートし・・・同様に繰り返し最終的に1グループが100件(行)~150件(行)になるようにしたいのです。つまり約3万件のデータを3*4*2*4*2=192分割(5列の値で分類)したい、そしてどのような範囲で分割したかという情報も得たいのです。
use strict;
use warnings;
use utf8;
use Encode;
binmode STDOUT, ':encoding(utf-8)';
my $dir = './data'; # 処理するディレクトリ
my $motoFile = 'customer.txt'; # もとファイル
open my $fh, '<:encoding(cp932)', "$dir/$motoFile" or die 'ファイルが開けません。',"$!";
my %sorted;
while (my $line = <$fh>) {
my $key = (split /,/, $line)[37];
push @{$sorted{$key}}, $line;
if (@{$sorted{$key}} == 1000) {
open OUT, '>>:encoding(cp932)', "$dir/$key.tmp" or die "Can't open: $!";
print OUT @{$sorted{$key}};
close OUT;
@{$sorted{$key}} = ();
}
}
open OUT, '>:encoding(cp932)', "$dir/out.txt" or die "Can't open: $!";
foreach my $key (sort { $b <=> $a } keys %sorted) {
if (-e "$key.tmp") {
open IN, '<:encoding(cp932)', "$dir/$key.tmp" or die "Can't open: $!";
print OUT while <IN>;
close IN;
}
print OUT @{$sorted{$key}} if @{$sorted{$key}};
}
close OUT;
#↓↓↓↓ここからフラグを作成するルーチン
# 行数を調べ3つに分けるルーチン
my @colum37;
open IN, '<:encoding(cp932)', "$dir/out.txt" or die 'ファイルが開けません。',"$!";
my @in = <IN>;
close IN;
my $gyousuu = scalar(@in);
my $amari = $gyousuu % 3;
if ($amari == 0) {
my $groupGyousuu = ($gyousuu-$amari)/3;
print "総行数は$gyousuu","で、1グループの行数は$groupGyousuu","ほど、余りは$amari\n";
# あまりが0の時、group1は@inの0行 ~$groupGyousuu-1行まで
# group2は@inの$groupGyousuu行 ~$groupGyousuu*2-1行まで
# group3は@inの$groupGyousuu*2行~$groupGyousuu*3-1行まで
foreach my $num (1..2) {
push @colum37, (split /,/, $in[$groupGyousuu*$num])[37]; # これは境目の先頭の37番目
}
print "@colum37\n"; #これでここまでは完成、分けるべき値がこの配列に入っている。
open OUT, '>:encoding(cp932)', "$dir/out.txt" or die "Can't open: $!";
foreach my $line (@in) {
my @line = split /,/,$line;
if ($line[37]>=$colum37[0]) {
$line[1] = 1;
}elsif ($line[37]>=$colum37[1] and $line[37]<$colum37[0]) {
$line[1] = 2;
}elsif ($line[37]<$colum37[1]) {
$line[1] = 3;
}
$line = join (',',@line);
print OUT $line;
}
close OUT;
}
elsif ($amari == 1) { この後未作成