您好我正在尝试在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
答案 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
更常用。