Преобразовать столбцы, которые имеют совпадение, в строку

Если вы являетесь пользователем RHEL, вы можете использовать:

service vsftpd status

Будет выдан следующий ответ, если служба не запущена:

vsftpd: unrecognized service

и если служба запущена на вашем сервере:

vsftpd (pid XXXX) is running...

Вы получаете ftp: connect: Connection refused, потому что в вашей системе установлен FTP-клиент, но FTP-сервер не установлен. Вы можете установить FTP-сервер vsftpdи попробовать то же самое, должно работать.

1
18.09.2019, 15:31
5 ответов

С помощью GNU Datamash

$ datamash -W groupby 1 collapse 2 < file | sed 's/,/ /g'
Locus7625186    GO0004866 GO0010951 GO0005615 GO0016021
Locus7360093    GO0004712 GO0007093
Locus1507198    GO0044212 GO0045944 GO0005634 GO0036464 GO0046982

(вы можете опустить вертикальную черту через sed, если вы не возражаете против запятых-разделителей по умолчанию ).

5
27.01.2020, 23:12
awk '!a[$1]{b[++p]=$1; a[$1]=$2;next} {a[$1]=sprintf("%s%s%s", a[$1], OFS, $2)} END {for (i=1; i<=p; i++) print b[i], a[b[i]]}' file

на основе этого поста как группировать строки в соответствии с первым полем/элементом

-1
27.01.2020, 23:12

Вы можете приблизиться к этому с помощью GNU sedпотокового редактора:

sed -Ee '
   :a
      $!N
      s/^((\S+)\s.*)\n\2(\s.*)/\1\3/
   ta
   P;D
' file

Результаты

Locus7625186 GO0004866 GO0010951 GO0005615 GO0016021
Locus7360093 GO0004712 GO0007093
Locus1507198 GO0044212 GO0045944 GO0005634 GO0036464 GO0046982

Это можно сделать и с помощью POSIX sed:

sed -e '
   :a
      $!N
      s/^\(\([^[:space:]]\{1,\}\)[[:space:]].*\)\n\2\([[:space:]].*\)/\1\3/
   ta
   P;D
' file
2
27.01.2020, 23:12

Другой sedподход, компактный, портативный и необычный:

sed 'N;/^\(.*\)\(.*\)\(\n\1\)/!P;s//\3\2/;D'
  • Он использует подход N;P;D, чтобы всегда иметь две строки в пространстве шаблона, поэтому он начинается с N, чтобы добавить следующую строку
  • /^\(.*\).*\n\1/соответствует строке, начинающейся с некоторого слова, пробела, другого слова с новой строки и повторяющегося начального слова, таким образом, две строки в буфере делят свое первое(Locus)слово. Если это не так, (!), Pнапечатайте первую строку, потому что она полная и мы можем позже избавиться от нее с помощьюD
  • Но если строки совпадают, значит, у нас есть две строки с одним и тем же первым словом, и мы можем сделать замену, удалив новую строку и повторяющееся слово. Вот почему я добавил еще две подгруппы в шаблон адреса для P, так что теперь мне не нужно повторять его, а использовать повторно, имея пустой шаблон
  • А теперь хитрость. :Я заменяю first second\nfirstна \nfirst second, поэтому в пространстве шаблонов есть пустая первая строка, за которой следует вторая строка с первым словом и все второе слово, которое у нас было до сих пор. Следующее Dтеперь удалит пустую первую строку и продолжит работу с уже собранной строкой. Включив \nв соответствие \3, мы не нуждаемся в \nв замене, которое не будет переносимым.
1
27.01.2020, 23:12

Предположим, что ваши ключевые значения сгруппированы, как в примере ввода:

$ awk '
    $1 != prev { printf "%s%s", ors, $1; prev=$1; ors=ORS }
    { printf " %s", $2 }
    END { print "" }
' file
Locus7625186 GO0004866 GO0010951 GO0005615 GO0016021
Locus7360093 GO0004712 GO0007093
Locus1507198 GO0044212 GO0045944 GO0005634 GO0036464 GO0046982

Если это не так, сначала отсортируйте файл.

1
27.01.2020, 23:12

Теги

Похожие вопросы