ここから質問投稿すると、最大10000ポイント当たる!!!! >>

テキストファイルの本文中に行番号を挿入するperlスクリプトが有る、と聞いて探しているのですが、見付かりません。何か手掛かりをご存知の方がいらっしゃいましたら、ご教示をお願いいたします。

※「本文中に行番号を挿入する」とは、(テキストエディタやOSなどの)環境・設定が異なる人同士で情報交換する際でも、同じ行番号で同じ行を特定できるようにすることを意図しています。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

$. が「現在の行番号」を表します. で, $_ が「読み込んだ行」なので "$.: $_" で「読み込んだ行の前に行番号を追加する」ということになります.


あと, 書式が必要なら指定できる printf もちゃんと用意されてます. 使える書式はだいたい C と同じです.
ということで Leopard なら
perl -ne 'printf "%06d: %s", $., $_' ファイル名
でいいし, Windows でも
printf "%06d: $s", $., $_ while <>;
というスクリプトを書いて
perl スクリプト ファイル名
で OK.
ただし複数のファイルを一度に処理しようとすると行番号が「前のファイルの続き」になるのは同じ.
    • good
    • 1
この回答へのお礼

望みが100%かないました。
ありがとうございました。感謝感激です。
今はコピペしているだけですが、解説文の意味を理解できるように
精進します。

お礼日時:2008/07/23 22:16

1つのファイルの各行に行番号を付けるということだと:


使ってる OS によるけど Unix なら
cat -n ファイル名
が最も簡単. ど~しても Perl を使いたいのなら
perl -ne 'print "$.: $_"' ファイル名
でいける (出力は適宜リダイレクトする). Windows はクオートまわりが弱いのでワンライナーにならないけど
print "$.: $_" while <>;
とだけ書かれたスクリプトを使う (こちらも出力は適宜リダイレクト) のがきっと楽だと思う.
複数のファイルに対しそれぞれ個別に行番号を付けるなら #2 に近い方法です.
    • good
    • 0
この回答へのお礼

期待していた以上に(初心者にも十分に)簡単な方法を教えて
いただきまして、感激です。perlに固執してはいませんので、catでも
(しかも簡単に)実現できることに非常に驚きましたし、また、
為になりました。
更に欲張って、質問しますが、行番号の桁数を指定する方法は
有りますか。例えば、6桁指定の場合は、
000001
000002
000003
となるような方法です。ちなみに、自分が利用できる環境は、
Windows Vista, Mac OS X 10.5 (Leopard)です。テキストファイルを
扱える限り、手段を問いません(始めから明言しておけば良かったですね)。

お礼日時:2008/07/23 21:28

こんなんでどうでしょうか。



#!/usr/bin/perl
use strict;
use warnings;

my $filename = 'text.txt'; #行番号を挿入したいファイル
my $tmpfile = 'text.tmp';
my $count = 1;

open my $fh, '<', $filename or die "can`t open $filename : $!\n";
open my $tmp, '>', $tmpfile or die "can`t write $tmpfile : $!\n";

while(<$fh>){
print $tmp "$count : $_";
$count++;
}

close $fh;
close $tmp;

unlink($filename) or die "can`t delete $filename : $!\n";
rename($tmpfile, $filename);
    • good
    • 0
この回答へのお礼

勉強不足のせいか、望みを実現できませんでした。
改めて勉強し直します。
ご回答、ありがとうございました。

お礼日時:2008/07/23 22:02

ここで解説しているスクリプトでできないでしょうか?


http://www.geocities.jp/m_hiroi/perl_tk/perltk07 …

ダウンロードはできませんが、最後にソースがあります。
    • good
    • 0
この回答へのお礼

勉強不足のせいか、望みを実現できませんでした。
改めて勉強し直します。
素早いご回答、ありがとうございました。

お礼日時:2008/07/23 22:01

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QPerlで特定行から特定行までを抜き出したい

皆さんのお知恵をお貸し頂ければ幸いです。

Perlで以下のようなことをしたいと考えています。
例えば、次のようなテキストファイルがあったとします。

example.log
==================================
aaaa
hogehoge
test
okok
perl
script
==================================

上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。
イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

このような場合、どういう風にすればいいのでしょうか?
恐れ入りますが、ご教授頂ければ幸いです。

それでは、どうぞよろしくお願い致します。

Aベストアンサー

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $flag = 0 }
  elsif ($flag) { print "$data\n" }
}
close FH;

で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^;

open FH, "example.log" or die $!;
while (<FH>) {
  print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/;
}
close FH;

※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $fl...続きを読む

Qファイルの行数取得

超初心者です。

いま、表計算的なスクリプトを記述しています。

あるファイルの行数を取得する関数ってあるんでしょうか?

ファイルに記述されている数値を足したり引いたりするのですが、forを使っての計算の際にファイルの行数が必要となりました。

Aベストアンサー

Perlにですね。ないはずです。
行数とはファイルに書かれた改行文字の個数ということなので
実際にファイルを全て読み込まないと行数はわかりません。
以下のように色々な方法があると思います

#### 単純な例
$a = 0;
open FD, "<file.txt" || die $!;
while (<FD>) {
$a++;
}
close FD;
print "行数:$a\n";

### 少しマニアックな方法
open FD, "<file.txt" || die $!;
@a = <FD>;
close FD;
print "行数:" . ($#a + 1) + "\n";


### 反則的方法(外部コマンド) ... UNIXの場合
print "行数:" . `wc -l file.txt` . "\n";

Q○文字目に文字挿入

お世話になっています。
正規表現の文字置換s///gを使って数字の3桁目に-を挿入したいですが、どうしたらいいのかわかりません。

どなたか教えていただけないでしょうか。

5770001

577-0001

にしたいのでしが…

Aベストアンサー

試してないのですが
s/(.{3})(.*)/$1-$2/;
でよいはずです。

数字確定ならば\dでも可。

Qsedの置換文字に変数を使用したいのですが・・・

あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。

例:
X="a"
Y="b"
echo test.txt | sed 's/${X}/${Y/g}' >test.txt

sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?

Aベストアンサー

' ・・・' で囲まれた中の$はそのままドルマークです。変数展開をするなら、'・・・'で囲んではいけません。

何も囲まないか、"・・・"で囲むかです。

Q複数のCSVファイルを一つのCSVファイルに

ディレクトリ内に複数あるCSVファイルを一つのCSVにまとめたいのですが、方法がわからないので教えて下さい。
ファイルの読み出しと追加書き込みを繰り返せば良いとは思っています。
ディレクトリ内のファイルを検索するところまでは出来ました。

Aベストアンサー

  my $path = "./data";  #csvのあるディレクトリ
  opendir(DIR, $path) || die "Error!!";
  my @dirs = grep /\.csv$/i, readdir(DIR);
  closedir(DIR);

  if(open(OUT,">./mix.csv")){
    for my $fname (sort @dirs){
      if(open(IN,"$path/$fname")){
        my @lines = <IN>;
        print OUT @lines;
        close(IN);
      }
    }
    close(OUT);
  }

#ファイルを順に読み込んで書き込んでいるだけです。テキトウに改造してみてください。
#動作確認はしてないです。
#または、perlから、OSのコピーコマンドを呼んでファイルを結合してもいいと思います。

Qテキストファイルの結合

はじめまして。配列とか変数でFORでループさせれ
ばいいのかなと思うのですが変数の取り扱いがわ
かりません。あるフォルダに拡張子なしの . の
後連番のテキストファイルがあります(SGML出力)。
その連番順にテキストを結合したファイルを作成
したい。
条件として"a086.xxx"のファイルについて処理し
たいです。よろしくお願いします。

ファイル名 中身
a084.000 .............
a085.000 .............
a086.000 abc.......xxx
a086.001 123.......xxx


a086.036 xyz.......xxx
a087.000 .............

結合したファイルの中身
abc.......xxx
123.......xxx



xyz.......xxx

フォルダの中のそのファイルの個数はその都度
違います。

下記のように処理したいファイル名は抽出して
みたのですがその後どうすればいいのかわかり
ません。また、ファイル名を抽出しないでその
まま処理するものでしょうか。

opendir ( DIR , "a:\\S603000" ) or die;

while($dir = readdir (DIR) ){
if ( $dir =~ /a086/ ){
print "$dir\n";
}
}
closedir ( DIR );

はじめまして。配列とか変数でFORでループさせれ
ばいいのかなと思うのですが変数の取り扱いがわ
かりません。あるフォルダに拡張子なしの . の
後連番のテキストファイルがあります(SGML出力)。
その連番順にテキストを結合したファイルを作成
したい。
条件として"a086.xxx"のファイルについて処理し
たいです。よろしくお願いします。

ファイル名 中身
a084.000 .............
a085.000 .............
a086.000 abc.......xxx
a086.001 123.......xxx


a086.036 xyz...続きを読む

Aベストアンサー

kinokoyasan2004さんのはいざファイルを開くとき、
open(IN,"$dir");
とやってしまっています。
これでは、Perlスクリプトが動いてるディレクトリに目的のファイルがないと意味がありません。

というわけで、

$indir = 'A:/S603000'; #探しに行くディレクトリ
$outdir = './output.dat'; #書き出すファイル

open(OUT,"> $outdir") or die $!;

opendir(DIR, $indir) or die $!;

while ($list = readdir(DIR)) {

if(-f "$indir/$list" && $list =~ /^a086\.[^\.]+$/i){

open(IN, "< $indir/$list") or die $!;
while (<IN>){print OUT;}
close(IN);

print OUT "\n";

}

}

closedir(DIR);

close(OUT);

kinokoyasan2004さんのはいざファイルを開くとき、
open(IN,"$dir");
とやってしまっています。
これでは、Perlスクリプトが動いてるディレクトリに目的のファイルがないと意味がありません。

というわけで、

$indir = 'A:/S603000'; #探しに行くディレクトリ
$outdir = './output.dat'; #書き出すファイル

open(OUT,"> $outdir") or die $!;

opendir(DIR, $indir) or die $!;

while ($list = readdir(DIR)) {

if(-f "$indir/$list" && $list =~ /^a086\.[^\.]+$/i){

open(IN, "< $indi...続きを読む

QPerlで行頭にある文字が含まれている行を全部削除して詰めたい

perl初心者です。以下のようにデータがならんでいる時、
test111 aaaaaaaaabbbbbbbbcccccc
test112 aaaaccccabbbbbbbbcccccc
test113 aaaaccaaabbbbbbbbcccccc
test114 acccaaaaabbbbbbbbcccccc

test111 aacaaaaaabbbbbbbbcccccc
test112 accaaaaaabbbbbbbbcccccc
test113 aaacccaaabbbbbbbbcccccc
test114 aaaaaccaabbbbbbbbcccccc

test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。

途中からわかりません。
行を削除する関数が調べても見つからないのです。

#!/usr/bin/perl ;
open(IN, "test.doc") or die ;

open(OUT, ">testout.doc");

while(<IN>) {
chomp ;
if (/(\S+)/) {

$name = $1 ;

if ($name =~ /^test112(\S+)/) {
#ここでマッチさせて、一気に行を削除して、しかも行を詰めたいのですが

;

}
print OUT " \n" ;
}
}
close (IN) ;
close (OUT) ;

大変困っております。宜しくお願いします。

perl初心者です。以下のようにデータがならんでいる時、
test111 aaaaaaaaabbbbbbbbcccccc
test112 aaaaccccabbbbbbbbcccccc
test113 aaaaccaaabbbbbbbbcccccc
test114 acccaaaaabbbbbbbbcccccc

test111 aacaaaaaabbbbbbbbcccccc
test112 accaaaaaabbbbbbbbcccccc
test113 aaacccaaabbbbbbbbcccccc
test114 aaaaaccaabbbbbbbbcccccc

test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。

途中からわかりません。
行を削除する関数が調べても見つからないのです。

...続きを読む

Aベストアンサー

一致しなかったときのみ出力するということで、

while(<IN>){
unless(/^test112/){
print OUT;
}
}

更に簡単に書くと、
while(<IN>){
print OUT unless(/^test112/);
}
となります。

削除にこだわるなら、
while(<IN>){
s/^test112\s.+//;
print OUT;
}
あたりでしょうか。

もしくは、明示的に削除したいなら、
while(<IN>){
if(/^test112\s.+/){
$_ = "";
}
print OUT;
}
というふうに、カラの文字列を代入してやるのも、値を削除するときの常套手段ですね。

Q数値かどうかの判定方法

$aに代入されているものが数値かどうかを判定するにはどのようにしたらよいのでしょうか?

Aベストアンサー

$a =~ /^[0-9]*$/
上記の場合、*は「直前のパターンの0回以上の繰り返し」の意味なので、0から9がなくても、つまり$aが空でもマッチしてしまいます。
なので、
$a =~ /^[0-9]+$/
としましょう。
(+は「直前のパターンの1回以上の繰り返し」)
また、0-9は\dで表すこともできるので
$a =~ /^\d+$/
と書くこともできます。

Q複数ファイルの読み込みについて

perl初心者です。

あるディレクトリから拡張子がdataであるファイルを全て読み込みたいのですが、方法がわかりません。
cshで書くと
foreach arg (*.data)
コマンド $arg

のようになりますが、perlだと
foreach $arg (@arg){
コマンド $arg

となりますよね?
引数がリストなのでよくわかりません。
そもそもperlではできないのでしょうか?


それともう一点ですが、ファイルオープンするときに
foreachループの中で
open(FILE, "$arg");
とすることは可能ですか?
上の質問と組み合わせて全てのファイルを開いて作業を行いたいので。

説明が下手ですいません。補足しますのでよろしくお願いします。

Aベストアンサー

while(<*.data>)
{
## $_には、*.DATAなファイル名が格納されている。
open(F,"$_"); ##openする。
while(<F>)
{
##読み出された内容が$_に格納されている。
print $_; ##出力してみる。
}
}

というのが最短コーディングです。

Qファイルからデータを読み込んで、配列に格納する方法

データファイル grep.dat があり、その中は
12345
67890
ABCDE
(EOF)
となっています。
 
このファイルの中身を読み込んで、配列 P[0]の
中に("12345","67890","ABCDE") に格納したい
のですが、どのように記述すればよいでしょうか。

Aベストアンサー

多次元配列に代入する場合

my @p;
open FILE, "grep.dat";
  @{$p[0]} = <FILE>;  ・・(a)
close FILE;

openの書式などは好みで変えてください。
結論を言えば、(a)のように書けばokです。

#細かい書式は他にもありますので調べてみるといいかもしれません。


人気Q&Aランキング