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

У меня есть следующий вход (тысяча строк). Я хочу, чтобы команда 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?
  • Bubble a до b с sed
  • Соответствие пяти столбцов в двух файлах с использованием Awk
  • Замена XML на основе содержимого атрибута с помощью sed
  • Переименование нескольких файлов, удаление всего одного экземпляра шаблона
  • Выход grep cdrecord
  • Фильтрация многострочных строк из журнала
  • 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

    SNR или уровень сигнала и шума в режиме ad-hoc

    Копирование файлов на основе даты / времени из поднабора каталогов

    запуск docker всегда терпит неудачу с «нет такого файла или каталога»

    Инструмент командной строки для создания файлов значков?

    Являются ли коды системного журнала все еще актуальными?

    Как установить VLC 1.1.10 или 1.1.9 в CentOS 5.6 или CentOS 6.0?

    Как настроить SELinux для разрешения исходящих подключений из сценария CGI?

    Использование данных, считанных из канала, а не из файла в параметрах команды

    Ipv6 Network недоступен Debian

    Broken PATH в CentOS 5.x

    сортировка игнорирует режим для второго ключа

    Доступ к Linux-серверу с компьютера Windows в графическом режиме через SSH

    Как сохранить PDF-файлы «text / pdf» на диске из входящей почты в Mutt

    Как я могу перечислить все зависимости, необходимые для установки PHP-Soap?

    Можем ли мы убить inetd, если ничего не использовать / нет config?

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