Perl';s Chomp:Chomp是删除整个单词而不是换行符

Perl';s Chomp:Chomp是删除整个单词而不是换行符,perl,Perl,我面临perl chomp函数的问题。 我有一个测试.csv如下: col1,col2 vm1,fd1 vm2,fd2 vm3,fd3 vm4,fd4 foreach (@array) { my @row = split (/,/,$_); print $row[1]; ### << Note that I am not printing "\n" } 我想打印此csv的第二个字段。这是我的代码: #!/usr/bin/perl -w use str

我面临perl chomp函数的问题。 我有一个测试.csv如下:

col1,col2
vm1,fd1
vm2,fd2
vm3,fd3
vm4,fd4
foreach (@array)
{
    my @row = split (/,/,$_);
    print $row[1];     ###  << Note that I am not printing "\n"
}  
我想打印此csv的第二个字段。这是我的代码:

#!/usr/bin/perl -w
use strict;

my $file = "test.csv";
open (my $FH, '<', $file);
my @array = (<$FH>);
close $FH;

foreach (@array)
{
    my @row = split (/,/,$_);
    my $var = chomp ($row[1]);     ###   <<< this is the problem
    print $var;
}
我真的不知道“1”是从哪里来的。实际上,最后一个字段可以打印如下:

col1,col2
vm1,fd1
vm2,fd2
vm3,fd3
vm4,fd4
foreach (@array)
{
    my @row = split (/,/,$_);
    print $row[1];     ###  << Note that I am not printing "\n"
}  
现在,我使用这些字段值作为DB的输入,DB INSERT语句由于这个不可见的换行符而失败。所以我想chomp会帮我的。它给了我“11111”,而不是狼吞虎咽

你能帮我弄明白我做错了什么吗

谢谢

阅读loldop的responce后添加更多信息:

如果我这样写,那么它不会打印任何东西(甚至上面提到的“11111”输出也不会打印)


也就是说,chomp删除了最后一个字符串和尾随的新行。

不过,开头是我的错。

chomp
function
return 1
如果您只是想去掉新行,可以使用正则表达式:

my $var = $row[1];
$var=~s/\n//g;

之所以只看到字符串
1
s,是因为您正在打印
$val
的值,该值是从
chomp
返回的值
chomp
不返回修剪后的字符串,它修改其参数并返回从末尾删除的字符数。由于它总是只删除一个
“\n”
字符,因此数组的每个元素都会得到
1
输出

您确实应该
使用warnings
而不是
-w
命令行选项,这里没有理由将整个文件读入数组。但是在使用三参数形式的
open
的词法文件句柄方面做得很好

下面是对您的程序的快速重构,它将实现您想要的功能

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

my $file = 'test.csv';
open my $FH, '<', $file or die qq(Unable to open "$file": $!);

while (<$FH>) {
    chomp;
    my @row = split /,/;
    print $row[1], "\n";
}
#/usr/bin/perl
严格使用;
使用警告;
my$file='test.csv';

打开我的$FH,“所以,我对这个看起来很简单的任务整天困扰着我感到很沮丧。我真的很感激每一个回应的人

最后,我使用Text::CSV perl模块,然后调用每个CSV字段作为数组引用。在使用Text::CSV之后,不需要运行chomp

代码如下:

#!/usr/bin/perl 
use warnings;
use strict;
use Text::CSV;


 my $csv = Text::CSV->new ( { binary => 1 } )  # should set binary attribute.
                  or die "Cannot use CSV: ".Text::CSV->error_diag ();


open my $fh, "<:encoding(utf8)", "vm.csv" or die "vm.csv: $!";

<$fh>;  ## this is to remove the column headers.

while ( my $row = $csv->getline ($fh) )
{
    print $row->[1];
}
后来,我将这些单独的值拉入数据库



谢谢大家。

chomp
如果此函数成功结束,返回
1
。所以,只要
chomp$$mygoodvar=$\u0@pavel:是的。但这不是文档中回答的直接问题。甚至谷歌也不行。我觉得这很简单。文档中说,[chomp]返回从其所有参数中删除的字符总数。所以它返回
1
,因为它删除了一个换行符。@Borodin:true。但在这种情况下,它也会删除最后一个字符串,这是不可取的。谢谢你的时间它不会删除最后一个字符串。您正在咀嚼
$row[1]
,它将从
$row[1]
的末尾删除一个换行符。打印
$row[1]
的值,您将看到。您使用替换的原因是什么?这个任务很奇怪为什么不呢?也许这很奇怪,但它很有效,并且符合他的目的:)因为正则表达式是一种昂贵的工具,真的。实际上,此任务只需要一个:查找最后一个字母,与
\n
进行比较,如果为true,则删除。我知道,要杀死一只鸟,你得用大炮,好吗。这是你的风格,诺里斯先生。这个替换也删除了最后一个字,没有明显的输出。谢谢。@raz3r:当有一个非常好的内置函数
chomp
专门用于删除字符串结尾的行终止符时,使用正则表达式替换(特别是只匹配一次的全局替换)来删除字符串结尾的行终止符似乎有悖常理。您提到的第二个foreach循环不起作用。我编辑了我的原始问题,并在其底部添加了这些信息。我想我不应该使用“拆分”。我不确定,但我认为我要查找的第二个字段在执行“拆分”后有一些不可见的字符。但是除了“拆分”之外,我想不出其他任何东西:)loldop,我同意你在代码板上提到的。我已经做过那个练习了。但这对我提到的CSV不起作用。A非常感谢你的时间。谢谢。仅供参考:也许你的CSV真的很奇怪,你需要使用CPAN模块,比如或类似的东西。不,我是在Ubuntu的vi编辑器中手工编写的。我自己创建了这个CSV,以便在这个论坛上发布。我实际使用的CSV是一个不同的CSV,但它显示的行为与我上面提到的完全相同。谢谢你抽出时间,就这样。非常感谢你。这很好用。不过,我无法理解我的方法出了什么问题。谢谢你的时间。@Dheeraj:请试着理解。您正在打印chomp的返回值
chomp
返回1,因此您正在打印1。相反,你应该在
$row[1]
中打印
chomp
ed数据。有趣的是,这段代码在我的fedora上工作,但在ubuntu上,它没有输出。它们都在运行perl 5.10.1。实际上,在ubuntu上,除非我在print语句中添加“\n”,否则不会显示输出。可能是错误或其他原因。@Dheeraj:我很确定您的数据文件是空的,或者打开的
失败。我已经修改了上面的解决方案:请尝试此代码,因为原始代码忽略了打开的错误,并继续执行。
#!/usr/bin/perl
use strict;
use warnings;

my $file = 'test.csv';
open my $FH, '<', $file or die qq(Unable to open "$file": $!);

while (<$FH>) {
    chomp;
    my @row = split /,/;
    print $row[1], "\n";
}
#!/usr/bin/perl 
use warnings;
use strict;
use Text::CSV;


 my $csv = Text::CSV->new ( { binary => 1 } )  # should set binary attribute.
                  or die "Cannot use CSV: ".Text::CSV->error_diag ();


open my $fh, "<:encoding(utf8)", "vm.csv" or die "vm.csv: $!";

<$fh>;  ## this is to remove the column headers.

while ( my $row = $csv->getline ($fh) )
{
    print $row->[1];
}
fd1fd2fd3fd4