
Perlでのテキスト処理について質問です。
テキストファイルの中身が下記のようになっています。
【テキスト編集前】
---------------------------------------
test ,abc ,AB ,VI ,SS ,ma ---1行目
test ,abc ,AC ,PI ,VS ,ma ---2行目
test ,abc ,BA ,SS ,VS ,ma ---3行目
test ,abc ,BA ,VI ,VS ,ma ---4行目
test ,cde ,AA ,VI ,SS ,mb ---5行目
test ,cde ,CC ,PE ,VS ,mb ---6行目
test ,cde ,BC ,PI ,SS ,mb ---7行目
test ,cde ,AC ,PI ,SS ,mc ---8行目
---------------------------------------
2列目(abc/cde)と6列目(ma/mb/mc)が同じ行に対しては
1行にまとめて出力したいと思っています。
この時、1列目、4列目、5列目はマージした形にし
(同一文字は一度だけ出力、同一でない文字は/区切りで出力)、
2列目、6列目は同一文字をそのまま出力し、
3列目に関しては、該当する行の先頭行の文字列を
出力したいと思っています。
下記が当方の希望しているPerl実行後の出力結果です。
【テキスト編集後】
---------------------------------------
test ,abc ,AB ,VI/PI/SS ,SS/VS ,ma
test ,cde ,AA ,VI/PE/PI ,SS/VS ,mb
test ,cde ,AC ,PI ,SS ,mc
---------------------------------------
このような編集をPerlで実行したいと思っているのですが、
どのような記述をすれば実行できるのか教えて頂けないでしょうか。
当方、Perlを始めたばかりで基本的なことを
伺っているのかもしれませんが
すみませんが、ご了承ください。
宜しくお願いいたします。
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
ところで普通はカンマの後ろに空白を置いて、前には置かないんじゃないですかね。
use strict;
use warnings;
use autodie;
use v5.10;
sub dump_data {
my $data_ref = shift;
given (ref($data_ref)) {
when ("ARRAY") {
say join(',', @{$data_ref});
}
when ("HASH") {
foreach my $e (sort keys %{$data_ref}) {
dump_data($data_ref->{$e});
}
}
default {
warn "invalid data";
}
}
}
sub get_contents {
my $fh;
if (@ARGV) {
open $fh, '<', shift @ARGV;
}
else {
$fh = *DATA;
}
chomp(my @lines = <$fh>);
close $fh;
@lines;
}
#main
my %data;
foreach my $line (get_contents) {
my @fields = split /\s*,\s*/, $line;
if (exists $data{$fields[0]}{$fields[1]}{$fields[5]}) {
my $ary_ref = $data{$fields[0]}{$fields[1]}{$fields[5]};
foreach my $i (0, 3, 4) {
$ary_ref->[$i] .= "/$fields[$i]" if index($ary_ref->[$i], $fields[$i]) < 0;
}
}
else {
$data{$fields[0]}{$fields[1]}{$fields[5]} = \@fields;
}
}
dump_data(\%data);
__END__
test ,abc ,AB ,VI ,SS ,ma
test ,abc ,AC ,PI ,VS ,ma
test ,abc ,BA ,SS ,VS ,ma
test ,abc ,BA ,VI ,VS ,ma
test ,cde ,AA ,VI ,SS ,mb
test ,cde ,CC ,PE ,VS ,mb
test ,cde ,BC ,PI ,SS ,mb
test ,cde ,AC ,PI ,SS ,mc
No.3
- 回答日時:
新規行を配列等に保存しておいて、2、6列目の同じ行が現れたら保存しておいた行を修正するというようなやり方があります。
use strict;
my @result;
NEXT: while (<DATA>) {
my @line = split /[,\s]+/;
foreach my $ref (@result) {
if ($line[1] eq $$ref[1] and $line[5] eq $$ref[5]) {
$$ref[0] .= "/$line[0]" if $$ref[0] !~ /\b$line[0]\b/;
$$ref[3] .= "/$line[3]" if $$ref[3] !~ /\b$line[3]\b/;
$$ref[4] .= "/$line[4]" if $$ref[4] !~ /\b$line[4]\b/;
next NEXT;
}
}
push @result, \@line;
}
print join(',', @$_), "\n" foreach @result;
__DATA__
test ,abc ,AB ,VI ,SS ,ma
test ,abc ,AC ,PI ,VS ,ma
test ,abc ,BA ,SS ,VS ,ma
test ,abc ,BA ,VI ,VS ,ma
test ,cde ,AA ,VI ,SS ,mb
test ,cde ,CC ,PE ,VS ,mb
test ,cde ,BC ,PI ,SS ,mb
test ,cde ,AC ,PI ,SS ,mc
No.2
- 回答日時:
まあ,丸投げですなあ>No.1
こういうのって・・・他の人はどう作るかわからないけど
最低限
プログラムではなく手動でやるときにどうするのか?
ってことが自分で整理できないと何もできないんだよね.
質問者は
したい作業を手動でエディタでできるのかい?
エディタでできるなら次にその工程を整理して
一個一個の作業を整理して
出来るかぎり小さな作業にばらして
その小さな作業を一個一個プログラムにするとか
そういうことができないのかな?
そうすれば,自然とプログラム全体ができるし
どこをコード化できないか切り分けもできるでしょう
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlのプログラミング 部分入れ...
-
Perlでファイルの末尾から指定...
-
テキストファイルで提出とは?
-
perl の open について教えてく...
-
Perl言語について。
-
ファイルをディレクトリ分配の...
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlでリテラル値はメモリにど...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlについて
-
perlのrequireの動き方について...
-
perlの構文でカンマの意味が分...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
pandasでまとめてインデックス...
-
<IN>; を単独で使う
-
サブルーチンの結果
-
perlで読み込んだURLを配列に入...
-
Perlのサンプルを見ていると
-
データの日付でソートをしたい
-
Perl ファイルを読込んで日付の...
-
perlの無名配列の使い方を教え...
-
Pythonの再帰関数の動作の流れ...
-
行・列の整理! perl
-
ExcelをCSV書き出す場合のシー...
-
エクセルVBA コードが同じでも...
-
awkスクリプトでダブルクォーテ...
-
batファイルでrenameができませ...
-
VBAでCSVファイルを途中行まで...
-
Windowsで複数のファイルを同じ...
-
where can I buy snowbord in t...
-
ReadLineでの読み出し行を指定する
-
バッチファイルの作り方(CSV→...
-
C言語で特定の行を抽出する方法...
おすすめ情報