Сделать все записи в файле ascii в один столбец в awk

У меня есть следующий файл

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}}' file

но я не знаю, как получить их в один столбец. Не говоря уже о том, что первые записи не такие, как ожидалось.

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

Любая идея о том, как получить желаемый вывод в два столбца? Любая помощь более чем приветствуется!!!


person Thanos    schedule 21.02.2014    source источник
comment
Вы можете поместить их все в одну строку и прокрутить строку.   -  person fedorqui 'SO stop harming'    schedule 21.02.2014
comment
@fedorqui: Спасибо за ответ. Я уже пытался поместить их в одну строку, но я не знаю, как сделать эту строку столбцом.   -  person Thanos    schedule 21.02.2014
comment
Вы хотите, чтобы количество записей, указанное во второй строке, равнялось нулю, если данных не существует? Или просто упорядочить существующие данные?   -  person potong    schedule 22.02.2014
comment
@potong: я хочу, чтобы после 2-й строки (т.е. начиная с 3-й) поместить все данные в один столбец, имея при этом новый столбец, в котором будет подсчитываться количество записей, начиная с 1.   -  person Thanos    schedule 25.02.2014


Ответы (5)


Запрос ОП put all entries after 4096 in one column. Другие решения просто предполагают его номер записи 2. Этот gnu awk должен позаботиться об этом, а также о проблеме с пробелами в конце строки:

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

PS вам нужно gnu awk из-за нескольких символов в RS

person Jotne    schedule 22.02.2014

Используя 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
 ...
person Filippo Lauria    schedule 21.02.2014

Это поможет:

$ awk 'NR>2{$1=$1;print}' OFS='\n' file 
person Chris Seymour    schedule 21.02.2014
comment
Большое спасибо за ответ! Как я могу добавить столбец, начиная с 1 и заканчивая 4096? - person Thanos; 21.02.2014
comment
Не думал, что вам действительно нужно количество строк, вы можете использовать nl для этого awk 'NR>2{$1=$1;print}' RS=' ' file | nl -n ln - person Chris Seymour; 21.02.2014
comment
+1 Не знаю, зачем кому-то отменять голосование за эту дерзкую остроту. Я бы использовал это в любой день вместо ответа вверху. - person jaypal singh; 25.02.2014

Это можно сделать с помощью GNU awk, который может использовать регулярное выражение в качестве разделителя повторов (RS):

gawk -v RS="[[:space:]]+" 'NR > 3 { print NR-3, $0 }' file
person Community    schedule 22.02.2014

Это может сработать для вас (GNU sed):

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

Это удаляет первую строку. Сохраняет последовательность чисел от 1 до числа, содержащегося во второй строке, в области удержания и удаляет вторую строку. Соединяет первое число на следующей строке с первым числом в удерживаемом пространстве и добавляет новую строку. Распечатывает сопряжение и повторяет. Когда последнее число последней строки совпало, все оставшиеся порядковые номера соединяются с нулем.

person potong    schedule 22.02.2014
comment
Это дает правильный вывод для данной даты, но не останавливается до тех пор, пока счетчик не достигнет 4096 строк. Он не начинается после записи с 4096 и сразу после столбца с номером 2 - person Jotne; 22.02.2014
comment
@Jotne Я не понимаю твоего комментария. Вы имеете в виду, что процесс должен прекратиться после того, как данные будут исчерпаны, даже если во второй строке указано 4096 строк? Однако я обнаружил ошибку в решении, касающуюся условия конца файла, поэтому пока удалю ее. - person potong; 22.02.2014