Perl / Ruby单线程数组操作

时间:2013-04-24 23:27:29

标签: ruby perl

您好我正在尝试在perl(或ruby)中创建一个单行程序,将文件中的数据读入数组,并在第10个元素之后使用换行符将其打印在列中。

文件就像这样

Name
Course1
Mark1
Course2
Mark2
Course3
Mark3
Course4
Mark4

应该像这样显示

Name   Course1  Mark1   Course2   Mark2   Course3   Mark3   Course4   Mark4

这是我试过的目标

perl -ne '@a=split"\n",$_;print join("\t"=>splice@a,0,10)' Data.txt 

4 个答案:

答案 0 :(得分:5)

这不起作用,因为您在一次读取一行时拆分换行符。您需要-0777才能使其正常运行。

您也只打印前10个元素,因此您需要引入循环。

perl -0777nE'@F = split /\n/; say join "\t", splice @F,0,10 while @F' Data.txt 

这需要利用-a

perl -F'\n' -0777naE'say join "\t", splice @F,0,10 while @F' Data.txt 

或者我们可以采取完全不同的方法。简短又甜蜜:

perl -pe's/\n/\t/ if $. % 10' Data.txt

如果没有10列的倍数,那么将以尾随制表符而不是换行符结束。好的,不太好。那怎么样

perl -0777pe's/\n(?!\z)/ ++$i % 10 ? "\t" : "\n" /eg' Data.txt

更新您已将问题更改为请求固定宽度字段。

如果你事先知道宽度(比如说场之间10 + 2个字符= 12):

perl -F'\n' -0777naE'say pack "(A12)9 A*", splice @F,0,10 while @F' Data.txt 

如果你不这样做:

perl -MList::Util=max -F'\n' -0777naE'
   $w = 2 + max map length, @F;
   say pack "(A$w)9 A*", splice @F,0,10 while @F;
' Data.txt 

答案 1 :(得分:2)

ruby -e 'ARGF.map{|l|l.strip}.each_slice(10) {|a| puts a.join "\t"}' Data.txt

答案 2 :(得分:0)

池上的我打败了它。但无论如何我会发布我的。

perl -pe 'tr/\n/\t/ if $. % 9 != 0'

编辑: 啊,甚至更好。感谢ikegami(对于$.,我忘记了那个)。

答案 3 :(得分:0)

数据样本只有九行,因此无法方便地放入十行存储桶中。我添加了一个占位符,因此我的文本文件如下所示:

Name
Course1
Mark1
Course2
Mark2
Course3
Mark3
Course4
Mark4
-----
Name
Course1
Mark1
Course2
Mark2
Course3
Mark3
Course4
Mark4
-----

我会在Ruby中做这些事情:

puts ARGF.lines.map(&:chomp).each_slice(10).map{ |a| a.join(' ') }

这给了我一个输出:

Name Course1 Mark1 Course2 Mark2 Course3 Mark3 Course4 Mark4 -----
Name Course1 Mark1 Course2 Mark2 Course3 Mark3 Course4 Mark4 -----

使用制表符代替空格很简单:将' '替换为"\t",但如何将其留作读者的练习。

map(&:chomp)删除尾随行结尾,以便打印时字段可以存在于一行中。 each_slice(10)一次抓取十个数组元素,这会产生一个数组数组,每个子数组包含十个字符串。最终map{ |a| a.join(' ') }使用空格或选项卡连接子数组(如果更改为"\t")。或者,可以使用a * ' 'a * "\t"代替join,但join更常用。