Sed 在awk中将ascii文件中的所有条目设为一列

Sed 在awk中将ascii文件中的所有条目设为一列,sed,awk,grep,gawk,Sed,Awk,Grep,Gawk,我有以下文件 CHO 1 4096 26 20 0 0 0 0 0 0 0 0 0 0 0 0 0 3 5 15 8 14 9 7 13 10 12 9 5 3 3 2 2 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 6 8 5 5 7 13 13 33 23 29 44 51 56 42 39 31 21 24 18 18 1

我有以下文件

CHO 1
4096
26 20 0 0 0 0 0 0 0 0 
0 0 0 0 0 3 5 15 8 14 
9 7 13 10 12 9 5 3 3 2 
2 0 0 0 0 0 0 1 1 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 0 1 0 0 0 
0 0 0 0 0 0 1 0 0 0 
0 0 0 0 1 0 0 0 0 0
6 8 5 5 7 13 13 33 23 29 
44 51 56 42 39 31 21 24 18 18 
18 30 44 43 51 67 102 110 130 130 
100 96 87 49 25 16 4 1 1 0
0 0 0 0 0 0
我要做的是将所有条目放在
4096
之后的一列中。所需的输出如下所示

1 26
2 20
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
...
4096 0
我不知道如何用awk来做。例如,我尝试使用

awk-F'\n'{if(NR==1){printf$0}else{printf$0}'文件

但我不知道如何让他们进入一个专栏。更不用说第一个条目不是预期的了

CHO 1409626 20 0 0 0 0 0 0 0 0 0 0 0 0 0 3 5

您知道如何获得所需的两列输出吗?欢迎任何帮助

这将实现以下目的:

$ awk 'NR>2{$1=$1;print}' OFS='\n' file 

使用Perl,可以重新适应以下情况:

#!/usr/bin/perl

use strict;
use warnings;

my @lines = ('CHO 1', '4096', #simulate line-by-line loading of the file
'26 20 0 0 0 0 0 0 0 0',
'0 0 0 0 0 3 5 15 8 14', 
'9 7 13 10 12 9 5 3 3 2', 
'2 0 0 0 0 0 0 1 1 0', 
'0 0 0 0 0 0 0 0 0 0', 
'0 0 0 0 1 0 1 0 0 0', 
'0 0 0 0 0 0 1 0 0 0', 
'0 0 0 0 1 0 0 0 0 0',
'6 8 5 5 7 13 13 33 23 29', 
'44 51 56 42 39 31 21 24 18 18', 
'18 30 44 43 51 67 102 110 130 130', 
'100 96 87 49 25 16 4 1 1 0',
'0 0 0 0 0 0');


my $first_line = shift @lines; #removes CHO 1
my $stop = shift @lines; #removes 4096 
my $i = 0;


foreach my $line (@lines) {
  $line =~ s/^\s*//;
  $line =~ s/\s*$//;

  my @parts = split(/\s+/, $line);
  foreach my $part (@parts) {
    print "$i $part\n"; #prints to stdout, maybe you want to print into a file
    $i++;
  }

}
这是输出:

0 26
1 20
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 0
15 3
16 5
 ...
125 0
 ...

以下是使用awk的另一种方法:

awk 'NR>2{for(x=1;x<=NF;x++) print y++,$x}' file
$awk'NR>2{for(x=1;x这可能适合您(GNU-sed):


这将删除第一行。在保留空间中存储从1到保留在第二行中的数字的序列,并删除第二行。将下一行的第一个数字与保留空间中的第一个数字配对,并添加新行。打印配对并重复。当最后一行的最后一个数字已匹配时任何剩余的序列号都与零配对。

OPs请求
将所有条目放在4096之后的一列中
。其他解决方案只需假定其记录号
2
。此
gnu awk
应解决该问题,以及行末尾的空格问题:

awk 'f{print ++x,$1} /4096/{f=1}' RS=" | *\n" file

PS您需要
gnu awk
,因为
RS

中有多个字符,这可以通过gnu awk完成,gnu awk可以使用正则表达式作为识别分隔符(RS):


你可以把它们都放在同一行,然后在字符串中循环。@fedorqui:谢谢你的回答。我已经试着把它们放在一行中了,但我不知道如何将这一行作为一列。在没有数据的情况下,你想让第二行指示的条目数成对为零吗?还是只想对存在的数据进行排序?@poton:I want在第二行之后(即从第三行开始),将所有数据放在一列中,同时有一个新列将“计数”从1开始的条目数。非常感谢您的回答!我如何才能添加一个从1开始到4096结束的列?我认为您实际上不需要行计数,您可以使用
nl
进行
awk'NR>2{$1=$1;print}“RS=”file | nl-n ln
+1不知道为什么有人会取消这个看起来厚颜无耻的一行。我会在顶部的答案上使用它。这会为给定的日期提供正确的输出,但它不会在计数器结束4096行之前停止。它不会在记录后以
4096
开头,也不会在列号之后开始e> 2
@Jotne我不理解您的评论。您的意思是,即使第二行指示4096行,数据用完后,该过程也应停止?但是,我在解决方案中发现了一个有关文件结束条件的错误,因此将暂时删除它。
$ awk 'NR>2{for(x=1;x<=NF;x++) print y++,$x}' file
0 26
1 20
2 0
3 0
4 0
5 0
6 0
7 0
---
---
122 0
123 0
124 0
125 0
sed -r '1d;2{s/.*/seq -s: &/e;s/$/:/;h;d};G;:a;/:/!d;/^\s*\n/{s///;h;$!d;x;s/:/ 0\n/g;s/.$//p;d};s/^(\S+)\s*([^\n]*\n)([^:]*):/\3 \1\n\2/;P;s/[^\n]*\n//;ba' file
awk 'f{print ++x,$1} /4096/{f=1}' RS=" | *\n" file
gawk -v RS="[[:space:]]+" 'NR > 3 { print NR-3, $0 }' file