Intereting Posts
Симметричная разностная труба? Проблема при запуске скрипта Как я могу запустить команду, если мой экран изменил состояние в режиме ожидания на включение и наоборот AWUS051NH v2 не вводит в Kali Linux Как просмотреть 10-битные видео H264 (hi10p) в видеоиграх GStreamer, таких как Totem? Как файлы tar с отсортированным порядком? Какой инструмент (я) следует использовать для проверки моего оборудования на наличие ошибок? Текст в фильм из командной строки Перейти к следующему помеченному сообщению в Mutt «Файловая система только для чтения» на общем ресурсе NFS, разрешениях, файлах монтирования и экспорта выглядит нормально Сохранение конфигурации iptables на постоянной основе Переместить / tmp в оперативную память Очень медленное автозаполнение в Linux для Windows Получите необработанный ввод из командной строки (игнорируйте метасимволы оболочки) рекурсивный поиск и печать последнего файла tar.gz в каждом каталоге

Объединить строки по первому столбцу с помощью awk или sed

Как использовать awk в следующей ситуации?

Я хочу объединить строки, начинающиеся с того же столбца. После объединения (только в этом случае aaa , www , hhh ) сохраняется только первый столбец.

Файл может быть разделен пробелами или вкладками.

Пример ввода:

 aaa bbb ccc ddd NULL NULL NULL aaa NULL NULL NULL NULL NULL NULL aaa bbb ccc NULL NULL NULL NULL www yyy hhh NULL NULL NULL NULL hhh 111 333 yyy ooo hyy uuuioooy hhh 111 333 yyy ooo hyy NULL 

Желаемый результат:

 aaa bbb ccc ddd NULL NULL NULL NULL NULL NULL NULL NULL NULL bbb ccc NULL NULL NULL NULL www yyy hhh NULL NULL NULL NULL hhh 111 333 yyy ooo hyy uuuioooy 111 333 yyy ooo hyy NULL 

Основой этого является то, что я хочу создать очень простую файловую базу данных, где первый столбец всегда является идентификатором для объекта. Все строки, основанные на одном столбце идентификатора, объединяются.

Чтобы получить первые столбцы в каждой строке с помощью awk, вы можете сделать следующее:

 cat test| awk '{print $1}' aaa aaa aaa www hhh hhh 

Это ваши ключи для остальных линий. Таким образом, вы можете создать хэш-таблицу, используя первый столбец в качестве ключа, а второй столбец строки – как значение:

 cat test| awk '{table[$1]=table[$1] $2;} END {for (key in table) print key " => " table[key];}' www => yyy aaa => bbbNULLbbb hhh => 111111 

Чтобы получить весь остаток строки, начиная со столбца 2, вам нужно собрать все столбцы:

 cat test| awk '{line="";for (i = 2; i <= NF; i++) line = line $i " "; table[$1]=table[$1] line;} END {for (key in table) print key " => " table[key];}' www => yyy hhh NULL NULL NULL NULL aaa => bbb ccc ddd NULL NULL NULL NULL NULL NULL NULL NULL NULL bbb ccc NULL NULL NULL NULL hhh => 111 333 yyy ooo hyy uuuioooy 111 333 yyy ooo hyy NULL 

Вот и все, надеюсь, это поможет 😉

Кто-то может ответить в awk или sed, но версия Python проста и может быть вам полезна.

 #!/usr/bin/env python input_file = 'input.dat' in_fh = open(input_file, 'r') input_order = [] seen = {} for line in in_fh: # Remove the newline character... line = line[:-1] # Separate the first column from the rest of the line... key_col, sep, rest_of_line = line.partition(" ") rest_of_line = sep + rest_of_line # If we've seen this key already, concatenate the line... if key_col in seen: seen[key_col] += rest_of_line # ...otherwise, record the ordering, and store the new info else: input_order.append(key_col) seen[key_col] = rest_of_line in_fh.close() # Dump the ordered output to stdout for unique_col in input_order: print unique_col + seen[unique_col] 

Это более интересное приложение coreutils, я подозреваю, что он не очень эффективен при большом вводе, поскольку он вызывает объединение для каждой строки на входе.

 touch outfile while read; do join -a1 -a2 outfile <(echo $REPLY) > tmp mv tmp outfile done < infile 

Чтобы повысить его эффективность, может помочь сохранение outfile и tmp в ramdisk.

редактировать

Или без временных файлов:

 out="" while read; do out=$(join -a1 -a2 <(echo -n "$out") <(echo -n "$REPLY")) done < infile echo "$out" 

И вот однолинейный PERL:

 $ perl -e 'my %h; while(<>){chomp; @a=split(/\s+/); $k=shift(@a); $h{$k}.=join(" ", @a) . " "; } map{$h{$_}=~s/\s*$//; print "$_ $h{$_}\n}keys(%hash);' infile