我想重写下面的文本,把它分成一行三个字符串。我从一个文件中读取文本作为一个数组。接下来,我把数组(4行)的所有元素连接到一个标量变量中。然后,我尝试在每第三个空格出现时拆分连接的元素。我的代码如下所示。
open ($TMP, "< TTaaInLittler.txt") or die "open 'TTaaInLittler.txt: failed $! ($^E)";
my @alldata=<$TMP>;
my $oneline=join(" ", @alldata);
close$TMP;
my $i = 0;
my $n = 3;
my @oneline=split(" ", $oneline, 10) if !( ++$i % $n );
print @oneline;
join()命令似乎可以工作,因为“print $oneline
“打印所有的文本。打印$oneline,但是打印4行。我期待的是一行。split命令似乎不工作,因为“print @oneline
“不做任何事情;没有错误,没有输出。有出路吗?请帮助。
TTAA 58231 63741 99823 15423 17003 70152 07604 29517 50586 04381
08513 40758 16182 11524 30967 31964 00510 25094 41365 25503
20241 53562 10512 15419 68542 07540 10656 76156 11024 88123
76950 09548 77999 31313 47708 82318=
TTAA 58231 63741
99823 15423 17003
70152 07604 29517
50586 04381 08513
40758 16182 11524
30967 31964 00510
25094 41365 25503
20241 53562 10512
15419 68542 07540
10656 76156 11024
88123 76950 09548
77999 31313 47708
82318=
3条答案
按热度按时间sczxawaw1#
一种方法是将所有输入分解为单词,然后每三个单词打印一行
当以
scriptname.pl input-filename
运行时,这将根据需要打印给定的输入文件。下面是一个必要的解释。
在Perl程序中,命令行中给出的参数是@ARGV,所以我们首先测试
@ARGV
是否可能为空;如果用户确实没有提供所需的参数(在这里输入文件名),程序就无能为力,我们die
(在这种情况下退出),并给出一条简洁的用法信息。†文件被读入
do
块中的字符串中。“input record separator”($/
变量)‡被本地化到块中,当它未被定义时,<>
操作符读取整个文件,文件名为@ARGV
,因此命令行中给出了(第一个)文件名。这被赋值给$content
,我们得到了文件。然后,split使用惯用的
' '
模式将该字符串用任何空格分隔,从而给出文件中的单词列表。最后,splice删除并返回前三个单词,这三个单词用空格连接在一起并打印在一行上,只要
@words
中还有任何元素,它就一直这样做(如果目标数组中没有三个元素,它就会删除所有元素,最终耗尽并清空数组)。所有这些都可以用一句话来概括,但在这里没有理由进行这样的杂技。
更重要的是,这可以通过使用库来完成,我们可以使用Path::Tiny::slurp将文件读入变量,然后使用List::MoreUtils::natatime(n-at-a-time)处理元素组。
† die语句末尾的
\n
隐藏了... at program-name line 5.
,后者通常会被打印出来,因为它在这里没有什么意义。这是非常基本的,还有更好的方法来提供和处理用户输入。参见Getopt::Long‡参见perlvar中的本节
42fyovps2#
请调查以下代码段是否符合您问题
注意:要从文件读取数据,请将
<DATA>
替换为<>
输出量
tv6aics13#
你的代码和
split
工作正常。要理解你的问题,你应该了解你的代码实际上是做什么的。首先如果你这样做。然后读取数组中的整个文件,但每一行末尾仍包含一个换行符。
然后你
join
每行加一个空格成一串。但是换行符不会被删除。例如,如果你有数组。
然后用一个空格加入这个数组,就得到了这个字符串
如果你打印这个字符串,那么它肯定会打印多行,因为它仍然包含多行。你可以在加入数组之前先把它吃掉,从而避免这个问题。
在上面有一个特殊的情况,当你使用
split
时,它只包含一个空格。然后它被当作split /\s+/
来处理。这意味着它不仅在一个空格字符上拆分,而且在所有空格字符上拆分,并且一次拆分多个空格字符。另外,有时候最好使用正则表达式来删除换行符。
默认情况下,
chomp
会删除一个特定于操作系统的换行符。因此在Linux上它只会删除\n
,在Windows上它会删除\r\n
。但是如果你在跨平台文件上工作,最好用正则表达式删除换行符,因为它总是处理这两种情况。当你把每一条线连接起来之后,你可以再把它分开。
因此,您的代码可能如下所示:
例如,要在一行上打印10个项目,可以使用类似下面的代码。完整示例:
但是在我看来,如果你想用whitesapce来分割所有的东西,而忽略那些行,你可以做得更好,把每一行都分割开,然后把结果推到一个数组上,这样做。
我之所以要这样做的一个原因是,这样做更容易工作,而且你也不需要读整个文件,例如,如果你愿意,你也可以很容易地把数字插入到
@tokens
中:您甚至可以进一步将所有内容简化为。
map
为每个数组元素执行代码块。在本例中,为<DATA>
中的每一行执行代码块,并将当前行放入特殊变量$_
中。一个单独的正则表达式默认情况下匹配$_
。m/\d+/g
匹配$_
,并将其拆分为多个元素,每行的所有元素都放入@tokens
中。