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

У меня есть следующий вход (тысяча строк). Я хочу, чтобы команда 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 

  • Как вставить текст в качестве альтернативы из двух файлов с общим шаблоном
  • Фильтрация многострочных строк из журнала
  • sed, чтобы заменить строки 2 строки после сопоставления шаблона в AIX 6.1
  • Как печатать строки между шаблоном 1 и 2-м совпадением шаблона2?
  • Как добавить парсеры вокруг текста
  • вырезать столбец int array в CSV без обрезки другого массива varchar
  • Sed: изменить каждое повторение не первого слова для каждого слова в тексте
  • Печать регулярного выражения Sed в файл .txt
  • 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

    Шифрование AES для распространения openwrt

    Подключитесь к серверу Ubuntu через SSH через Интернет

    Какие менеджеры пакетов используют популярные дистрибутивы Unix?

    Что означает, что сообщение электронной почты является «старым»?

    Не удается подключиться к Интернету в Ubuntu 10.10

    рекурсивно синхронизировать только определенные файлы из определенных подкаталогов с удаленного сервера

    Беспроводное устройство не отображается

    Samba с несколькими долями с одного сервера

    Расширения сертификатов при создании и подписании сертификатов с помощью openssl

    Все мои файлы были удалены после того, как я попытался улучшить свой звук

    Двойная загрузка Linux с окнами 10

    Как восстановить карту памяти в ее исходное состояние, поскольку она показывает двойной размер, когда я пытаюсь разбить его в fdisk?

    Подсчет количества строк, которые я набираю в vim

    Переход от Debian 6 Устойчивость к сжатию до версии для тестирования

    Почему Debian Linux поддерживает до 128TiB виртуальное адресное пространство для каждого процесса, но только физическую память 64TiB?

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