2013-04-24 116 views
0

您好,我正在尝试在perl(或ruby)中将单个数据从文件读取到数组中,并在第10个元素之后用换行符在列中打印。Perl /红宝石单线阵列操作

的文件是这样的

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"=>[email protected],0,10)' Data.txt 
+0

在输出中如何分隔列;与标签? – 2013-04-24 23:32:56

+0

是的,他们被标签分开 – user1976336 2013-04-24 23:37:28

+0

你说“每10个元素之后”,但你的例子只有9. 9或10? – ikegami 2013-04-24 23:47:40

回答

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 
+0

非常感谢你的工作:)。现在添加到它,是否可以使用“字段大小”来使列很好地对齐? – user1976336 2013-04-24 23:47:59

+0

+1对于很好的解释 – chrsblck 2013-04-24 23:48:23

+0

@ user1976336,你说你想使用制表符。如果你想要固定宽度的字段,这是一个完全不同的问题! – ikegami 2013-04-24 23:50:00

0

池上打我给它。但我会发布我的反正。

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

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

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

它会帮助OP如果你*解释*代码在做什么。不要给人鱼,教他们如何钓鱼。 – 2013-04-25 02:39:16

0

数据示例仅为9行,因此不适合方便地放入十行存储桶中。我添加了一个占位符,所以我的文本文件看起来像:

 
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)每次抓取10个数组元素,这会产生一个数组数组,每个子数组包含10个字符串。最后的map{ |a| a.join(' ') }将空格或标签(如果更改为"\t")连接到子阵列。或者,可以使用a * ' 'a * "\t"代替join,但join更常用。