
データファイルを一行ずつ読み込んで、文字列を一文字ずつコンマ区切りにしたいと思っています。たとえば、
xyz → x,y,z
としたいと思っています。
今、data.txt に
abc
defgh
という2行が書いてあります。
perl -nla -e '@chars= split(//,@F[1]); print join(",",@chars);' data.txt
とすると
a,b,c
d,e,f,g,h
という出力が無事に得られました。
どうせ、data.txt は一列しか使っていないので、
@F[0] の代りに $_ を使ってみました。
perl -nle '@chars= split(//, $_); print join(",",@chars);' data.txt
しかし、結果は
a,b,c,
d,e,f,g,h,
のように、各行の最後に余計なコンマが付いてしまいます。
なぜでしょうか?
一列しかデータがないので、@F[0] と $_ は同じだと思っていたのですが、なにか違うのでしょうか?
No.6ベストアンサー
- 回答日時:
ほぼ、既に答が出ているようですが、cygwinのperlでは改行コードを0x0A
で、data.txtはdos形式の改行だからということのようですね。
以下のように入力セパレータが0x0Aで、dos形式のファイルをchompして
も、0x0Dが残ることがわかります。
$ cat check_chomp.pl
#!/usr/bin/perl
use warnings;
use strict;
print "--- Now Return Code\n";
print_char_cord($/);
my $file = shift || 'data.txt';
open my $fh, '<', $file or die "$file: $!";
while ( my $line = <$fh> ) {
print "\n--- Before chomp\n";
print_char_cord($line);
chomp $line;
print "\n--- After chomp\n";
print_char_cord($line);
}
close $fh or die "$file: $!";
sub print_char_cord {
my $str = shift;
while ( $str =~ m/^(.)(.*)/s ) {
printf( "%s = 0x%X\n", $1, ord $1 );
$str = $2;
}
print "\n";
}
$ perl check_chomp.pl ~/tmp/data.txt
--- Now Return Code
= 0xA
--- Before chomp
a = 0x61
b = 0x62
c = 0x63
= 0xD
= 0xA
--- After chomp
a = 0x61
b = 0x62
c = 0x63
= 0xD
--- Before chomp
d = 0x64
e = 0x65
f = 0x66
g = 0x67
h = 0x68
= 0xD
= 0xA
--- After chomp
d = 0x64
e = 0x65
f = 0x66
g = 0x67
h = 0x68
= 0xD
ワンライナーでchompしたいときは、例えば次のように$/を変えてやれば、
OKです。
$ perl -nle '@chars= split(//, $_); print join(",",@chars);' ~/tmp/data.txt
a,b,c,
d,e,f,g,h,
$ perl -nle 'BEGIN{$/="\x0D\x0A"} @chars= split(//, $_); print join(",",@chars);' ~/tmp/data.txt
a,b,c
d,e,f,g,h
$
あっという間に検証用のコードまで・・・すごい・・・。ありがとうございます!
なるほど、
● cygwin perl の改行文字が \n
● windows の改行文字が \r\n
なので、
$/ = "\r\n";
と最初に設定して、削除したい改行文字を設定すればいいのですね!
No.5
- 回答日時:
> しかし、chomp $_ のあとも変化がありません・・・。
chomp は改行文字を削除するものです。改行文字が含まれていない場合、何もしません。
> 下の方のところでもありましたが
> cygwin の perl の問題でしょうか・・・。
私自身は Windows を使っていないのであくまで一般論ですが、data.txt の改行文字が
CRLF で cygwin の Perl の改行文字が LF のみとなっている場合は、今回のような現象
が生じる可能性があるかもしれません。すなわち -nl によって除去されるのは LF のみ
で $_ には末尾に CR が付き、-a によるフィールド分割では CR が空白文字類に含まれ
るので除去される、といった具合です。
No.3
- 回答日時:
文字列の末尾に1つの半角スペースまたはタブが付いているのは考えられると思います。
$_ へはそのまま格納されますが、@F への格納では空白類が捨てられます。$_ と $F[0]
の文字列の長さを確認してはどうでしょうか。
$ perl -nla -e 'print length($_), ", ", length($F[0]);' data.txt
この回答への補足
data.txt には改行が入っていないのですが、、、
確かに length($_) の方が一つ多い値でした。
しかし、chomp $_ のあとも変化がありません・・・。
下の方のところでもありましたが
cygwin の perl の問題でしょうか・・・。
No.2
- 回答日時:
かわらんなあ
---
$ perl -v
This is perl, v5.8.8 built for i386-linux-thread-multi
$ cat /etc/redhat-release
CentOS release 5.3 (Final)
$
$ cat data.txt
abc
defgh
$ perl -nle '@chars= split(//,$_); print join(",",@chars);' data.txt
a,b,c
d,e,f,g,h
$ perl -nla -e '@chars= split(//,$F[0]); print join(",",@chars);' data.txt
a,b,c
d,e,f,g,h
$ perl -nla -e '@chars= split(//,@F[0]); print join(",",@chars);' data.txt
a,b,c
d,e,f,g,h
この回答への補足
あれ、cygwinでやったのが悪いのでしょうか・・
$ perl -v
This is perl, v5.8.7 built for cygwin-thread-multi-64int
(with 1 registered patch, see perl -V for more detail)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Perlのエラーについてご教授く...
-
openした後、closeしないでプロ...
-
perlで複数のファイルの処理に...
-
Perlで同じフォルダにある任意...
-
perlプログラミング 空白行削除
-
perlのプログラミング 部分入れ...
-
Perlで特定文字列から特定文字...
-
perl 正規表現でエラー
-
perl の open について教えてく...
-
Perl言語について。
-
ファイルをディレクトリ分配の...
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
-
perlでリテラル値はメモリにど...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
テキストファイルで提出とは?
-
Perlのエラーについてご教授く...
-
openした後、closeしないでプロ...
-
perlをバージョンアップしたら...
-
INDIRECT 横に再度抽出したい
-
Perl の外部モジュールの利用方法
-
Strawberry Perl for Windows ...
-
Perlで同じフォルダにある任意...
-
perl 正規表現でエラー
-
PerlでUTF-8のファイルの文字列...
-
Perlで特定文字列から特定文字...
-
C言語の問題について
-
どこがおかしいのか教えてくだ...
-
arduino の割り込み処理について
-
perlのflock関数でロックをかけ...
-
bashスクリプト
-
Wallpaper Engineでおすすめの...
-
perlの構文でカンマの意味が分...
-
Perl(Windows)の文法について
-
Windows版のPerlについて
おすすめ情報