Объединить строки по первому столбцу с помощью 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 

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

4 Solutions collect form web for “Объединить строки по первому столбцу с помощью awk или sed”

Чтобы получить первые столбцы в каждой строке с помощью 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 
  • Как сделать замену sed (s /// g) на основе списка? Мне нужно поменять несколько слов, с другими соответствующими словами
  • удаление первого и последнего символов каждой строки из командной строки
  • Замена строк в файлах с содержимым файла
  • Как использовать SED или AWK для замены заполнителей в файле шаблона с содержимым переменной, содержащим специальные символы?
  • Заменить только в определенной строке диапазона
  • Как получить «\» вместо «» после замены sed?
  • grep и найдите следующее значение:
  • grep + регулярное выражение для соответствия слову, расположенному перед последним словом
  • Перемещение строк данных в один столбец при сохранении заголовков строк
  • Удалить до заданного символа, начиная с заданной строки
  • Вставьте строку после блока текста с помощью sed
  • Linux и Unix - лучшая ОС в мире.