Слияние дублированных строк, которые имеют одинаковые первые три поля

У меня есть следующий вход (тысяча строк). Я хочу, чтобы команда sed объединила дублированные строки с теми же первыми тремя полями, которые добавили только разные поля или удалили «N / A»:

 D04005;4;279;0;0;SSM-4-1 D04005;5;40;0;0;SSM-5-1 LE040A;1;363;(26.3);N/A;SM-1-1 LE040A;1;363;(27.4);N/A;SM-1-2 

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

 D04005;4;279;0;0;SSM-4-1 D04005;5;40;0;0;SSM-5-1 LE040A;1;363;(26.3);(27.4);SM-1-1/SM-1-2 

  • удалить строки в файле list_file из другого файла (ов)
  • sed: игнорировать строку, начинающуюся с пробела для соответствия
  • Почему sed печатает первую строку из файла, даже если не удается найти соответствующие группы
  • Отфильтруйте пути из текстового файла, который глубже, чем их непосредственный предшественник
  • Удалить строки, содержащие путь к файлу с помощью sed
  • найти строки, которые не заканчиваются на «rpms» с sed
  • grep + регулярное выражение для соответствия слову, расположенному перед последним словом
  • Быстрый способ удалить строку из чрезвычайно большого файла
  • 3 Solutions collect form web for “Слияние дублированных строк, которые имеют одинаковые первые три поля”

     sed ':n s|;N/A;|;|g;$!N s|^\(\([^;]*;\)\{3\}\)\(.*\)\n\1|\1\3;|;tn P;D ' <<\IN D04005;4;279;0;0;SSM-4-1 D04005;5;40;0;0;SSM-5-1 LE040A;1;363;(26.3);N/A;SM-1-1 LE040A;1;363;(27.4);N/A;SM-1-2 LE040A;1;363;(28.5);N/A;SM-1-3 LE040A;1;363;(29.6);N/A;SM-1-4 IN 

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

    Это портативно написано, но немного легче писать, если вы можете использовать -E расширенные регулярные выражения (как вы могли бы с версиями BSD или GNU)

     sed -E ':n s|;N/A;|;|g;$!N s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn P;D' 

    Если вы хотите все это на одной строке:

     sed -Ee:n -e's|;N/A;|;|g;$!N;s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn' -eP\;D 

    … будет работать, но я никогда не очень любил однострочники

    В любом случае, выход из первого там:

    ВЫВОД

     D04005;4;279;0;0;SSM-4-1 D04005;5;40;0;0;SSM-5-1 LE040A;1;363;(26.3);SM-1-1;(27.4);SM-1-2;(28.5);SM-1-3;(29.6);SM-1-4 

    Чтобы также переместить любое конечное поле, начинающееся с символа / SM- до SM- строки, и для разделения каждого из них с / , я считаю, что следующее должно работать:

     sed -E ':n s|;N/A;|;|g s|;(SM-[^;]*)$|/\1|;$!N s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn P;D' 

    Вы знаете, кстати, это может стать намного проще – и намного быстрее – если вы можете быть более ясными и более конкретными о том, что вам нужно. Для меня не похоже, что вы хотите объединить только три первых одинаковых поля на любые две последовательные строки и удалить поле, которое соответствует N/A из любой строки, и затем переместить SM- поля в хвост любого линия. Скорее, для меня это похоже на то, что все эти индивидуальные задания, которые вы назовете, на самом деле одно и то же, и что вы действительно хотите что-то вроде:

    • Если строка ввода найдена с тремя полями с буквой с буквой, с разделителями с запятой, то поле с плавающей точкой в ​​скобках, за которым следует другой разделитель двоеточия, затем поле N/A , мы должны сделать следующее:
      1. Проверьте, соответствует ли следующая строка этому описанию, и, если так, сравните первые три поля для текущей строки и следующей.
      2. Если совпадение найдено, сохраните только последнее поле из следующей строки, а затем повторите попытку, чтобы повторить попытку.
      3. Независимо от того, всегда удаляйте поле, которое соответствует N/A , и заменяет последнее ; с / .
    • Независимо от того, напечатайте все, что остается в stdout.

    Вы видите, как это отличается? Это серия выполняемых задач, которые зависят от одного начального условия. Если вы можете быть настолько ясными, то ваши матчи не будут компенсировать вашу общность во время обработки.

    Если я прав, то может работать следующее:

     sed ' \|;N/A;|!b s||/|;$!N \|^\(.*(\)\(.*)\)\(.*\)\(\n\1\)\(.*)\)|!P s||\4\2;(\5\3|;D ' <<\IN D04005;4;279;0;0;SSM-4-1 D04005;5;40;0;0;SSM-5-1 LE040A;1;363;(26.3);N/A;SM-1-1 LE040A;1;363;(27.4);N/A;SM-1-2 LE040A;1;363;(28.5);N/A;SM-1-3 LE040A;1;363;(29.6);N/A;SM-1-4 IN 

     D04005;4;279;0;0;SSM-4-1 D04005;5;40;0;0;SSM-5-1 LE040A;1;363;(26.3);(27.4);(28.5);(29.6)/SM-1-1/SM-1-2/SM-1-3/SM-1-4 

    … Здесь это -E на одной строке …

     sed -e'\|;N/A;|!b' -e's||/|;$!N;\|^\(.*(\)\(.*)\)\(.*\)\(\n\1\)\(.*)\)|!P;s||\4\2;(\5\3|;D' 

    … или in -E расширенный синтаксис …

     sed -Ee'\|;N/A;|!b' -e's||/|;$!N;\|^(.*\()(.*\))(.*)(\n\1)(.*\))|!P;s||\4\2(\5\3|;D' 

    TXR:

     @(repeat) @ (cases) @id;@f2;@f3;@val1;@nil;@sm1 @id;@f2;@f3;@val2;@nil;@sm2 @ (do (put-line `@id;@f2;@f3;@val1;@val2;@sm1/@sm2`)) @ (or) @line @ (do (put-line line)) @ (end) @(end) $ txr data.txr data D04005;4;279;0;0;SSM-4-1 D04005;5;40;0;0;SSM-5-1 LE040A;1;363;(26.3);(27.4);SM-1-1/SM-1-2 
     sed -r ':a;N;s!;N/A!!g;s/^(([^;]*;){3})(.*)\n\1/\1\3;/;T;s!^(([^S][^;]*;){3,})(S*SM-[^;]*);(([^S][^;]*;){1,})(.*)!\1\4\3/\6!;ta' inputfile 

    Несмотря на то, что подразумеваемая математика вашего комментария только для 6 полей на выходе предполагает, что есть только пары, это циклическая версия с изменениями вывода SM-1-1 / SM-1-2 при совпадении.

    Interesting Posts

    Использование двойного щелчка в окне терминала в Fedora 24 с помощью vim для выполнения копирования и вставки

    Как заставить «yum search» использовать локальные метаданные / кеш?

    Использование переменных в скрипте systemd init

    Файл, доступный только с правами root

    MTS MBlaze 3G USB Dongle в монетном дворе 14 Cinnamon

    Можно ли прикрепить `kinit` к первой попытке` ssh` без билета Kerberos?

    Получение ошибок сегментации изнутри glib и gobject – Я ДУМАЮ, Я хочу построить / статически связать с независимой версией glib2

    Статическая привязка устройства ACC CDC

    Как извлечь данные из XML-файла

    Нужна помощь в расшифровке скрипта bash

    При связывании с неопределенной версией библиотеки правильный выбор?

    Ваша система не настроена на правильное выполнение KVM

    Почему программированию на C не нужны сценарии компилятора и оболочки?

    cygwin: ls -i сообщает неправильный номер inode для файлов в UNC-пути

    Разгон Intel Nvidia для вычислений (CUDA)

    Linux и Unix - лучшая ОС в мире.