perlによる連番の自動生成
-
yam
perlによる連番の自動生成
初めて投稿させて頂きます。
まずはC言語での質問でない点、何卒お許しください。
現在、独学でPerlを勉強しはじめ、まだ2か月ほどの初心者です。
また以前にもほとんどプログラムの経験がございません。
そのため要領を得ない質問かもしれませんが、そちらについてもお許し頂きたく思います。
質問についてでございますが、ファイルのデータ処理について困っております。
ある「data.txt」というファイルに以下のような改行コードで区切られたデータがあるとします。
##番号:1##
##名前:田中##
##住所:東京##
##番号:2##
##名前:山田##
##住所:大阪##
##番号:3##
##名前:佐藤##
##住所:愛知##
##番号:3##
##名前:小林##
##住所:福岡##
##番号:4##
##名前:太田##
##住所:広島##
……
以上のようなデータが1000件あるとします。
そして「番号」のところをご覧頂きたいのですが、4番目の「番号」は本来なら4なのですが、間違って3となっております。そのため、それ以下の番号が間違って振られております。また1000件のデータには、そのような箇所が所々あるため、最終的に番号は「番号:1020」となっております(本当なら「番号:1000」とならなければなりません)。
そこでperlで連番を自動生成させればよいのではないかと考えました。
具体的には「ファイルの読み込み」→「『番号』の箇所に連番を生成させて、置換する」→「ファイルの書き込み」といったことを考えております。
しかし初心者のためうまくいかず、またネットでサンプルとなるものはないかと探したのですが、こちらもうまく見つけることができませんでした。
そこで皆様のお知恵をお借りしたく、投稿させて頂きました。何卒、よろしくお願い致します。
なお、環境でございますが、
Mac0S 10.4
perl -v 5.8.6
エディタ mi
以上でございます。
再度ながら、何卒、よろしくお願い致します。
まずはC言語での質問でない点、何卒お許しください。
現在、独学でPerlを勉強しはじめ、まだ2か月ほどの初心者です。
また以前にもほとんどプログラムの経験がございません。
そのため要領を得ない質問かもしれませんが、そちらについてもお許し頂きたく思います。
質問についてでございますが、ファイルのデータ処理について困っております。
ある「data.txt」というファイルに以下のような改行コードで区切られたデータがあるとします。
##番号:1##
##名前:田中##
##住所:東京##
##番号:2##
##名前:山田##
##住所:大阪##
##番号:3##
##名前:佐藤##
##住所:愛知##
##番号:3##
##名前:小林##
##住所:福岡##
##番号:4##
##名前:太田##
##住所:広島##
……
以上のようなデータが1000件あるとします。
そして「番号」のところをご覧頂きたいのですが、4番目の「番号」は本来なら4なのですが、間違って3となっております。そのため、それ以下の番号が間違って振られております。また1000件のデータには、そのような箇所が所々あるため、最終的に番号は「番号:1020」となっております(本当なら「番号:1000」とならなければなりません)。
そこでperlで連番を自動生成させればよいのではないかと考えました。
具体的には「ファイルの読み込み」→「『番号』の箇所に連番を生成させて、置換する」→「ファイルの書き込み」といったことを考えております。
しかし初心者のためうまくいかず、またネットでサンプルとなるものはないかと探したのですが、こちらもうまく見つけることができませんでした。
そこで皆様のお知恵をお借りしたく、投稿させて頂きました。何卒、よろしくお願い致します。
なお、環境でございますが、
Mac0S 10.4
perl -v 5.8.6
エディタ mi
以上でございます。
再度ながら、何卒、よろしくお願い致します。
- bitter_fox
- 記事: 607
- 登録日時: 15年前
- 住所: 大阪府
Re: perlによる連番の自動生成
フォーラムルールによりますとyam さんが書きました: そこでperlで連番を自動生成させればよいのではないかと考えました。
具体的には「ファイルの読み込み」→「『番号』の箇所に連番を生成させて、置換する」→「ファイルの書き込み」といったことを考えております。
しかし初心者のためうまくいかず、またネットでサンプルとなるものはないかと探したのですが、こちらもうまく見つけることができませんでした。
そこで皆様のお知恵をお借りしたく、投稿させて頂きました。何卒、よろしくお願い致します。
とありますので、もしyamさんが作ったプログラムがあれば教えていただけますか?フォーラムルール さんが書きました: 2. どう取り組んで(作ったプログラムはどれで
3. どのようなエラーやトラブルで困っていて
Re: perlによる連番の自動生成
そこまで目的にピッタリなサンプルはそうそう無いと思います。yam さんが書きました:そこでperlで連番を自動生成させればよいのではないかと考えました。
具体的には「ファイルの読み込み」→「『番号』の箇所に連番を生成させて、置換する」→「ファイルの書き込み」といったことを考えております。
しかし初心者のためうまくいかず、またネットでサンプルとなるものはないかと探したのですが、こちらもうまく見つけることができませんでした。
しかし「ファイルの読み込み」、「置換」といった機能別に探していけば方法はだいたい分かるはずです。
実は先ほどPerlの知識がほとんど無い状態で自動生成プログラムを書いてみたのですが、
以下の4つのページに書かれていることを押さえれば作れてしまいました。
(正規表現については知らないとやや戸惑うかもしれませんが、別に難しい使い方をしているわけではありません)
http://www.kent-web.com/perl/chap2.html
http://www.kent-web.com/perl/chap6.html
http://www.kent-web.com/perl/chap7.html
http://www.kent-web.com/perl/chap9.html
答えのコードを書くほどのプログラムではないので、
とりあえずyam さんの手でできるだけ書いてみることをお勧めします。
[追記]
この連番データの場合ですと、正規表現を使わなくても一応は自動生成プログラムを書くことができます。
-
yam
Re: perlによる連番の自動生成
bitter_foxさん、h2so5さん、わざわざお返事くださり、本当にありがとうございます。
ただ、こちらが至らないながらも、わざわざご指摘頂いたこと、本当に感謝です。後学に致します。ありがとうございました。
ただ、まだ途中段階であることと、それに関連してまだ途中段階であるために本来の目的とは多少ずれている点がございますが、お許しください。また読み込みのファイル内におけるデータはいちばん最初に質問させて頂いたものである点を、ご了承ください。
【出力結果】
1##番号:1##
2##番号:2##
3##番号:3##
4##番号:3##
5##番号:4##
---------------------
結果としては、「番号」の箇所をうまく抜き出して出力することができました。また行頭の部分ですが連番を振ることができました。
【問題点】
1. 今回はマッチ =~ を使いましたが、「番号:<数字>」の<数字>のところだけを取り出せないものかと悩んでおります。
2. 上記1.と関連して、連番は行頭に出ましたが、行頭ではなく<数字>のところに出ないものかと悩んでおります。
3. 上記1.と2.と関連して、本当はマッチではなく置換(s///)を使って、「番号:」以下の数字の部分を取り出した後、連番を発生させて置き換えたいと考えているのですが、置換をどのように組み合わせて使ってよいのかわかりません。
4. 本来の目的としては、連番を生成させた後、deta.txtに書き込みを行いたいのですが、どのようにしていいのかよくわかりません。h2so5さんからご紹介頂いたHPから(http://www.kent-web.com/perl/chap6.html),ファイルへの書き込みは と理解したのですが,生成された連番をどのように処理していいかわかりません(一度、配列のようにして処理するのでしょうか?)。
以上、もしよろしければお教え頂きたく思います。
よろしくお願い致します。
bitter_fox さんが書きました:
おしゃること、ごもっともです。申し訳ございませんでした。フォーラムルール さんが書きました: 2. どう取り組んで(作ったプログラムはどれで
3. どのようなエラーやトラブルで困っていて
ただ、こちらが至らないながらも、わざわざご指摘頂いたこと、本当に感謝です。後学に致します。ありがとうございました。
HPをご紹介頂いたこと、本当に感謝です。参考にさせて頂きました。ありがとうございました。h2so5 さんが書きました: 以下の4つのページに書かれていることを押さえれば作れてしまいました。
(正規表現については知らないとやや戸惑うかもしれませんが、別に難しい使い方をしているわけではありません)
http://www.kent-web.com/perl/chap2.html
http://www.kent-web.com/perl/chap6.html
http://www.kent-web.com/perl/chap7.html
http://www.kent-web.com/perl/chap9.html
答えのコードを書くほどのプログラムではないので、
とりあえずyam さんの手でできるだけ書いてみることをお勧めします。
bitter_fox さんが書きました: もしyamさんが作ったプログラムがあれば教えていただけますか?
お二人のご指摘を頂き,プログラムを組んでみました(なお、h2so5さんの紹介してくださったHP.参考になりました。ありがとうございました)。h2so5 さんが書きました: この連番データの場合ですと、正規表現を使わなくても一応は自動生成プログラムを書くことができます。
ただ、まだ途中段階であることと、それに関連してまだ途中段階であるために本来の目的とは多少ずれている点がございますが、お許しください。また読み込みのファイル内におけるデータはいちばん最初に質問させて頂いたものである点を、ご了承ください。
open(FILE, "data.txt");
$i = 1;
while(<FILE>){
chomp;
if($_ =~ /番号/){
print $i . $_ , "\n";
$i++;
}
}
close (FILE);
1##番号:1##
2##番号:2##
3##番号:3##
4##番号:3##
5##番号:4##
---------------------
結果としては、「番号」の箇所をうまく抜き出して出力することができました。また行頭の部分ですが連番を振ることができました。
【問題点】
1. 今回はマッチ =~ を使いましたが、「番号:<数字>」の<数字>のところだけを取り出せないものかと悩んでおります。
2. 上記1.と関連して、連番は行頭に出ましたが、行頭ではなく<数字>のところに出ないものかと悩んでおります。
3. 上記1.と2.と関連して、本当はマッチではなく置換(s///)を使って、「番号:」以下の数字の部分を取り出した後、連番を発生させて置き換えたいと考えているのですが、置換をどのように組み合わせて使ってよいのかわかりません。
4. 本来の目的としては、連番を生成させた後、deta.txtに書き込みを行いたいのですが、どのようにしていいのかよくわかりません。h2so5さんからご紹介頂いたHPから(http://www.kent-web.com/perl/chap6.html),ファイルへの書き込みは と理解したのですが,生成された連番をどのように処理していいかわかりません(一度、配列のようにして処理するのでしょうか?)。
以上、もしよろしければお教え頂きたく思います。
よろしくお願い致します。
Re: perlによる連番の自動生成
変数$iに正しい番号が入っているので、わざわざ間違った番号を抽出する必要はありません。yam さんが書きました: 1. 今回はマッチ =~ を使いましたが、「番号:<数字>」の<数字>のところだけを取り出せないものかと悩んでおります。
printfを使います。yam さんが書きました: 2. 上記1.と関連して、連番は行頭に出ましたが、行頭ではなく<数字>のところに出ないものかと悩んでおります。
printfを使えば置換は必要ありません。yam さんが書きました: 3. 上記1.と2.と関連して、本当はマッチではなく置換(s///)を使って、「番号:」以下の数字の部分を取り出した後、連番を発生させて置き換えたいと考えているのですが、置換をどのように組み合わせて使ってよいのかわかりません。
置換でも不可能ではないですがあまり良い方法ではありません。
data.txtとは別に書き込み用のdata_out.txtなどを開いておき、yam さんが書きました: 4. 本来の目的としては、連番を生成させた後、deta.txtに書き込みを行いたいのですが、どのようにしていいのかよくわかりません。
data.txtを1行ずつ開きながらdata_out.txtに書き込みを行い、
番号の行の時だけはdata.txtの内容を無視して正しい番号を書き込みます。
Re: perlによる連番の自動生成
perl -ne 's/(番号:)(\d+)/$1.++$i/e;print;' < data.txt
あえて解説しませんがこんな感じで。
参考になるでしょうか。
#ウインドウズのコマンドプロンプトではシングルクォートをダブルクォートに。
(追記)
2つ目の括弧いらなかった。
perl -ne 's/(番号:)\d+/$1.++$i/e;print;' < data.txt
あえて解説しませんがこんな感じで。
参考になるでしょうか。
#ウインドウズのコマンドプロンプトではシングルクォートをダブルクォートに。
(追記)
2つ目の括弧いらなかった。
perl -ne 's/(番号:)\d+/$1.++$i/e;print;' < data.txt
-
yam
Re: perlによる連番の自動生成
h2so5さん、ISLeさん、お返事ありがとうございます。
何とかうまく連番を生成させ、番号の間違えてある箇所を修正させることができまた。
特に参考になったのが、h2so5さんがご指摘くださった、
本当に感謝しております。ありがとうございました。
また質問させていただいた「番号」の連番の生成については、結局のところforで生成させ、配列化しました。
他のところ(「名前」と「住所」)についてはdata.txtから読み込みのあとにそれぞれを配列化しました。そしてすべての配列を一つずつ取り出して、新たな .txtに書き込むという手順をとりました。
ただ、せっかくh2so5さんがご指摘くださった、別の書き込み用のファイルを開いてから処理するというのはうまくいきませんでした。そのためターミナル(プロンプト)から直接コマンドを入力して処理しました。
それともう一つ、printfで処理する点もご指摘くださったのですが、こちらにつてもどうしていいかわかりませんでした。
しかし、この2点についてもできるということなので、今後頑張ってチャレンジしたいと思います。
それとISLeさんがお書きくださった、
以上、皆様、無事に解決することができました。
本当にありがとうございました。
何とかうまく連番を生成させ、番号の間違えてある箇所を修正させることができまた。
特に参考になったのが、h2so5さんがご指摘くださった、
の部分でした。このお考えは独学で勉強中のプログラム初心者である私にとっては、考えつかないことでした。h2so5 さんが書きました: data.txtとは別に書き込み用のdata_out.txtなどを開いておき、
data.txtを1行ずつ開きながらdata_out.txtに書き込みを行い、
番号の行の時だけはdata.txtの内容を無視して正しい番号を書き込みます。
本当に感謝しております。ありがとうございました。
また質問させていただいた「番号」の連番の生成については、結局のところforで生成させ、配列化しました。
他のところ(「名前」と「住所」)についてはdata.txtから読み込みのあとにそれぞれを配列化しました。そしてすべての配列を一つずつ取り出して、新たな .txtに書き込むという手順をとりました。
ただ、せっかくh2so5さんがご指摘くださった、別の書き込み用のファイルを開いてから処理するというのはうまくいきませんでした。そのためターミナル(プロンプト)から直接コマンドを入力して処理しました。
それともう一つ、printfで処理する点もご指摘くださったのですが、こちらにつてもどうしていいかわかりませんでした。
しかし、この2点についてもできるということなので、今後頑張ってチャレンジしたいと思います。
それとISLeさんがお書きくださった、
についてもうまくいかなかったのですが、お書きになってくださった内容を理解するためにいろいろ調べて勉強になりましたし、置換のs///を使ってもいけるのだという勉強になりした。この点についても今後チャレンジしてみたいと思います。h2so5 さんが書きました: perl -ne 's/(番号:)\d+/$1.++$i/e;print;' < data.txt
以上、皆様、無事に解決することができました。
本当にありがとうございました。
Re: perlによる連番の自動生成
これはいわゆるワンライナーというもので、端末からperlコマンドを起動するときにコマンドラインでプログラムを指定して、標準入出力に対して1行ずつ処理しています。yam さんが書きました:それとISLeさんがお書きくださった、についてもうまくいかなかったのですが、お書きになってくださった内容を理解するためにいろいろ調べて勉強になりましたし、置換のs///を使ってもいけるのだという勉強になりした。この点についても今後チャレンジしてみたいと思います。ISLe さんが書きました: perl -ne 's/(番号:)\d+/$1.++$i/e;print;' < data.txt
そのままだと結果は端末に出力されますのでファイルに記録したいときはリダイレクトします。
CygwinとUbuntuのbashでは動作したのですが。
後学のために出力されたエラーメッセージなど教えていただけないでしようか。
スクリプトに仕立てるとこんな感じになります。 in.txtを読み込んでout.txtに書き出すとなるとこんな感じになります。
-
yam
Re: perlによる連番の自動生成
ISLeさん、お返事ありがとうございます。
またスプリクトを示してくださっての詳しい説明にも感謝です。ありがとうございました。
そのため、文字化けが出た時点でうまくいかないものと思い、コマンドを実行させませんでした。
しかし今回文字化けしていても、それを無視して実行したところ、うまく処理されました。
それに比べて私の書いたものなんて、だらだら長くてお恥ずかしいかぎりです(でも生まれて初めてプログラムを書いて、そしてうまく処理されたので、その意味ではちょっと感動しました)。
それと#コメント部分のご指摘も参考になりました。ありがとうございました。
それから先ほどのエラーメッセージで思い出したのですが、ISLeさんがお書きになったスクリプトを実行させたところ、
perl -w data.pl Name "main::i" used only once: possible typo at data.pl line 4.
というメッセージがでました。ただ、処理についてはうまくできていましたので、このメッセージは無視してもいいかとも思うのですが、いかがでしょうか。
またスプリクトを示してくださっての詳しい説明にも感謝です。ありがとうございました。
前に「うまくいかなかった」と申し上げましたが、詳細を述べると、ターミナル(プロンプト)にコピペ、または打ち込むと「番号」の部分が文字化けしてしまいました。(こんな感じです→\347\225\252\345\217\267)。ISLe さんが書きました: そのままだと結果は端末に出力されますのでファイルに記録したいときはリダイレクトします。
CygwinとUbuntuのbashでは動作したのですが。
後学のために出力されたエラーメッセージなど教えていただけないでしようか。
そのため、文字化けが出た時点でうまくいかないものと思い、コマンドを実行させませんでした。
しかし今回文字化けしていても、それを無視して実行したところ、うまく処理されました。
こんなに短いスクリプトでうまく処理できるんですね!
それに比べて私の書いたものなんて、だらだら長くてお恥ずかしいかぎりです(でも生まれて初めてプログラムを書いて、そしてうまく処理されたので、その意味ではちょっと感動しました)。
それと#コメント部分のご指摘も参考になりました。ありがとうございました。
それから先ほどのエラーメッセージで思い出したのですが、ISLeさんがお書きになったスクリプトを実行させたところ、
perl -w data.pl Name "main::i" used only once: possible typo at data.pl line 4.
というメッセージがでました。ただ、処理についてはうまくできていましたので、このメッセージは無視してもいいかとも思うのですが、いかがでしょうか。
Re: perlによる連番の自動生成
$iという変数が突然出てきてしかも一回しか使われていないのだがタイプミスではないか?という警告ですね。yam さんが書きました:perl -w data.pl Name "main::i" used only once: possible typo at data.pl line 4.
というメッセージがでました。ただ、処理についてはうまくできていましたので、このメッセージは無視してもいいかとも思うのですが、いかがでしょうか。
これに関してはスクリプトを短くするためにあえて無視しました。
ふだんスクリプトを書くときはuse strict&use warningsを付けるようにしています。
本当にタイプミスしたときエラーで弾いてくれます。
-
yam
Re: perlによる連番の自動生成
ISLeさん、お返事拝読致しました。
ISLeさん、本当にいい勉強になりました。
いろいろご指摘、ありがとうございました。
なるほど、そう警告だったのですね。ISLe さんが書きました: $iという変数が突然出てきてしかも一回しか使われていないのだがタイプミスではないか?という警告ですね。
これに関してはスクリプトを短くするためにあえて無視しました。
私も長いプログラムが書けるようになったら use strict と use warnings を書くようにしなければなりませんね。ISLe さんが書きました: ふだんスクリプトを書くときはuse strict&use warningsを付けるようにしています。
本当にタイプミスしたときエラーで弾いてくれます。
ISLeさん、本当にいい勉強になりました。
いろいろご指摘、ありがとうございました。