2014-12-05 74 views
0

我像一个目录中的一些文件:串联并打印每个数组元素带有后缀

A.txt 
B.txt 
C.txt 

我想用新的后缀将它们打印:

#!/user/bin/perl 

my @dir_list_initial = `ls *.txt | sed 's/.txt//g' `; 
my $suffix = ".dat"; 

for (my $i=0; $i<=$#dir_list_initial; $i++){ 
print $dir_list_initial[$i] . $suffix; 
} 

我希望打印

A.dat 
B.dat 
C.dat 

但它打印

.datA 
.datB 
.datC 

回答

4

你可以尝试,

chomp(@dir_list_initial); 

后来

print $dir_list_initial[$i] . "$suffix\n"; 

@dir_list_initial阵列的每一个元件在字符串的结尾换行符。

更妙的是这将是完全跳过外壳,并且只使用perl的,

my @dir_list_initial = map { s|\.txt||; $_ } glob("*.txt"); 
+0

很好!作品:) – EpiMan 2014-12-05 13:39:16

+0

请在投票正确答案时发表评论。 – 2014-12-09 06:37:06

2

你通过运行ls做一半的计划。当你可以使用内建Perl机制来完成同样的工作时,不要掏腰包glob可以用ls完成你正在做的一切,你不必依靠ls命令(如果这是Windows?)。

另外,总是use strict;use warnings;在您的程序中,它可以通过捡到常见的错误为您节省大量的痛苦。

#! /usr/bin/env perl 
# 
use strict; 
use warnings; 
use feature qw(say); 

for my $file (glob "*.txt") { 
    chomp $file; 
    $file =~ s/\.txt$/.dat/; 
    say $file; 
} 

注意我使用s/.../.../代替一个后缀与另一个。你需要学习regular expressions。您的s/.txt//不正确。 .可以代表任何字符,并且您不指定.txt必须位于字符串的末尾。如果我的文件名为ftxtback.txt,则会将文件名更改为.datback.txt,这不是您想要的。

+1

'glob'返回的列表元素不需要'chomp'。这是最简单的使用非破坏性替代'使用5.014;说地图s/txt \ z/dat/ir,glob'* .txt'' – Borodin 2014-12-05 17:04:08

+0

是的,您在这种情况下不需要'chomp'。不过,我仍然习惯于使用它。不像旧的'chop',在不需要时使用'chomp'不会造成任何伤害。 – 2014-12-05 20:16:47

+0

什么?你'chomp' *每*字符串*无处不在*?这有点奢侈! – Borodin 2014-12-05 21:18:11

1

没有必要调用sed这里,PERL可以处理好:

my @dir_list_initial = `ls *.txt`; 
chomp @dir_list_initial; 
my $suffix = ".dat"; 
foreach (@dir_list_inital){ 
    s/\.txt$/$suffix/; # this alters @dir_list_initial 
    print "$_\n"; 
} 

,如果你有一个Perl比5.14更近,你也可以这样做:

use 5.014; 
my @dir_list_initial = `ls *.txt`; 
chomp @dir_list_initial; 
my $suffix = ".dat"; 
say s/\.txt$/$suffix/r foreach @dir_list_initial; # this doesn't alter the array. 

和,正如mpapec已经指出的那样,最好不要涉及外壳:

say s/\.txt$/.dat/r foreach <*txt>