Intereting Posts
Ejabberd: невозможно подключить веб-консоль Как найти и установить указать пакет по команде? Регулярное выражение для каждого слова, содержащего & с $ … $ Почему conda не использует символические ссылки для дублирования зависимостей? Как извлечь строки между двумя шаблонами в одном столбце? -ksh: income_ext.ksh: не найден Корица (Петра) разбилась. Открывается в резервном режиме Как разрешить использование crontab для локальных учетных записей, которые не разрешают интерактивный вход? Fedora 25 Cinnamon застрял в графическом цикле регистрации, tty login успешно Как вы используете перенаправление вывода в сочетании с здесь-документами и кошкой? Есть ли простой способ создать оболочку sudo? Как указать виртуальные машины QNAP из командной строки SSH? Почему root имеет доступ к моему x-серверу? Заменить последние символы в каждой строке Терминалу иногда не удается найти исполняемые файлы в локальном каталоге

таблица разбиения на основе соответствия ячейки столбцу

У меня есть большая разделительная матрица в файле в Linux:

Name ID ABC12 ABCD12 ABCD123 ABCD1234 ABC12 123456 XX YY ZZ JJ ABC12 123456 XX YY ZZ JJ ABCD12 123456 XX YY ZZ JJ ABCD12 123456 XX YY ZZ JJ ABCD123 123456 XX YY ZZ JJ ABCD123 123456 XX YY ZZ JJ ABCD1234 123456 XX YY ZZ JJ ABCD1234 123456 XX YY ZZ JJ 

Я хочу разбить эту матрицу на отдельные файлы на основе соответствия в 1-м столбце, [это большой файл, не может считать номера столбцов]

ожидаемый результат:

Файл 1;

 Name ID ABC12 ABC12 123456 XX ABC12 123456 XX 

Файл 2;

 Name ID ABCD12 ABCD12 123456 YY ABCD12 123456 YY 

Файл 3;

 Name ID ABCD123 ABCD123 123456 ZZ ABCD123 123456 ZZ 

Файл 4;

 Name ID ABCD1234 ABCD1234 123456 JJ ABCD1234 123456 JJ 

Полное решение awk :

 awk 'NR==1{ len=split($0,a_pos); for(i=1;i<=len;i++) a_keys[a_pos[i]]=i } NR>1{ if(!r[$1]++) { fn="file"++c; print "Name\tID\t"$1 > fn } print $1,$2,$(a_keys[$1]) > fn }' OFS='\t' file 
  • len=split($0,a_pos) – разделение 1-й строки на массив «ключей» (массив a_pos индексируется целыми числами)

  • for(i=1;i<=len;i++) a_keys[a_pos[i]]=i – flipping a_pos в массив a_keys который будет проиндексирован строковыми ключами (для дальнейшей обработки)

  • fn="file"++c – создание имени файла


Просмотр результатов:

 for f in file[0-9]*; do (echo "$f"; cat "$f"; echo); done 

Вывод ( file1 , file4 и file4 последовательно):

 file1 Name ID ABC12 ABC12 123456 XX ABC12 123456 XX file2 Name ID ABCD12 ABCD12 123456 YY ABCD12 123456 YY file3 Name ID ABCD123 ABCD123 123456 ZZ ABCD123 123456 ZZ file4 Name ID ABCD1234 ABCD1234 123456 JJ ABCD1234 123456 JJ 

Вы можете использовать awk :

 awk 'NR>1{if ($1!=p){N="file"++C; print "Name\tID\t"$1 >N}; print $1,$2,$(C+2)>N}{p=$1}' infile.txt 

Самый простой способ, который я могу придумать, – сохранить первую строку как переменную, а затем распечатать остальные по мере необходимости. Это, однако, требует сохранения всего входного файла в память:

 #!/bin/gawk -f { if(NR==1){ header[1]=$1; header[2]=$2; for(i=3;i<=NF;i++){ header[$i]=i; } } else{ data[$1][NR]=$2"\t"$(header[$1]); } } END{ OFS="\t"; for(i in data){ print header[1],header[2],i > i".txt" for(k in data[i]){ print i,data[i][k] >> i".txt" } } } 

Сохраните этот скрипт как foo.awk , сделайте его исполняемым ( chmod a+x foo.awk ) и запустите его в своем файле:

 foo.awk file 

Использование: ./split_matrix.awk input.txt

 #!/usr/bin/awk -f BEGIN { cnt = 1; } NR == 1 { for(i = 3; i <= NF; i++) { headers[$i] = i; } } NR > 1 { if( ! file_names[$1]) { file_names[$1] = cnt++; printf "%s %s %s\n", "Name", "ID", $1 > "file_"file_names[$1]; } printf "%s %s %s\n", $1, $2, $headers[$1] >> "file_"file_names[$1]; } 

тестирование

вход

 Name ID ABC12 ABCD12 ABCD123 ABCD1234 ABC12 123456 XX YY ZZ JJ ABC12 123456 XX YY ZZ JJ ABCD12 123456 XX YY ZZ JJ ABCD12 123456 XX YY ZZ JJ ABCD123 123456 XX YY ZZ JJ ABCD123 123456 XX YY ZZ JJ ABCD1234 123456 XX YY ZZ JJ ABCD1234 123456 XX YY ZZ JJ 

output (используйте tail -n +1 -- file* для печати имени файла и содержимого файла. Я нашел этот трюк здесь )

 ==> file_1 <== Name ID ABC12 ABC12 123456 XX ABC12 123456 XX ==> file_2 <== Name ID ABCD12 ABCD12 123456 YY ABCD12 123456 YY ==> file_3 <== Name ID ABCD123 ABCD123 123456 ZZ ABCD123 123456 ZZ ==> file_4 <== Name ID ABCD1234 ABCD1234 123456 JJ ABCD1234 123456 JJ