我有一个包含1列和800,000行的大文件
示例:
123
234
...
5677
222
444
我想将其转换为每行20个数字。
示例:
123,234,....
5677,
222,
444,....
我尝试使用像这样的while循环
while [ $(wc -l < list.dat) -ge 1 ]
do
cat list.dat | head -20 | awk -vORS=, '{ print $1 }'| sed 's/,$/\n/' >> sample1.dat
sed -i -e '1,20d' list.dat
done
但这太疯狂了。
有人可以提出更快的解决方案吗?
答案 0 :(得分:2)
pr
是正确的工具,例如:
$ seq 100 | pr -20ats,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40
41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60
61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80
81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
对于您的文件,请尝试pr -20ats, list.dat
根据列文本的宽度,您可能会遇到错误pr: page width too narrow
。在这种情况下,请尝试:
$ seq 100000 100100 | pr -40ats,
pr: page width too narrow
$ seq 100000 100100 | pr -J -W79 -40ats,
100000,100001,100002,100003,100004,100005,100006,100007,100008,100009,100010,100011,100012,100013,100014,100015,100016,100017,100018,100019,100020,100021,100022,100023,100024,100025,100026,100027,100028,100029,100030,100031,100032,100033,100034,100035,100036,100037,100038,100039
100040,100041,100042,100043,100044,100045,100046,100047,100048,100049,100050,100051,100052,100053,100054,100055,100056,100057,100058,100059,100060,100061,100062,100063,100064,100065,100066,100067,100068,100069,100070,100071,100072,100073,100074,100075,100076,100077,100078,100079
100080,100081,100082,100083,100084,100085,100086,100087,100088,100089,100090,100091,100092,100093,100094,100095,100096,100097,100098,100099,100100
-W
值的公式为(col-1)*len(delimiter) + col
,其中col
为所需列数
来自man pr
pr - 转换文本文件以进行打印
-a, - across 打印列而不是向下打印列,与-COLUMN一起使用
-t, - -omit-header 省略页眉和预告片;如果PAGE_LENGTH <= 10
则暗示-s [CHAR], - 分离者[= CHAR] 用单个字符分隔列,CHAR的默认值是不带-w和'no的字符 char'with -w。 -s [CHAR]关闭所有3列选项的行截断(-COLUMN | -a -COLUMN | -m) 除了-w设置
-COLUMN, - column = COLUMN 除非使用-a,否则输出COLUMN列和打印列。平衡列中的行数 在每页
-J, - join-lines 合并完整行,关闭-W行截断,没有列对齐, - sep-string [= STRING]设置分离 - 职责范围
-W, - page-width = PAGE_WIDTH 将页面宽度设置为PAGE_WIDTH(72)字符,截断行,除了-J选项设置,没有 与-S或-s
的关系
另见Why is using a shell loop to process text considered bad practice?
答案 1 :(得分:0)
如果您不想使用任何其他外部二进制文件,可以参考以下SO链接深入回答类似问题。
答案 2 :(得分:0)
如果你想使用sed:
sed -n '21~20 { x; s/^\n//; s/\n/, /g; p;}; 21~20! H;' list.dat
第一个命令
21~20 { x; s/^\n//; s/\n/, /g; p;},
在匹配21+(n * 20)的行上触发; N'GT; = 0。这里通过第二个命令在补充线上放置在保持空间中的所有内容:
21~20! H;
处理:
x;
将保持缓冲区的内容(20行)放入模式空间,并将当前行(21+(n * 20))放入保持缓冲区。在模式空间中:
s/^\n//
删除尾随的新行和:
s/\n/, /g
进行所需的替换。:
p;
打印现在20列的行。 之后,在保持缓冲区中读取下一行,然后继续该过程。