Хобрук: Ваш путь к мастерству в программировании

Замените шаблон частью совпадающей строки из той же строки в bash

У меня есть файл с одним json на строку следующего формата:

{"id":13, "url":"https://sub.domain.com/path", "dm":"-", "ip":"192.168.0.1"}
{"id":14, "url":"sub.domain2.com/?param=value", "dm":"-", "ip":"192.168.0.1"}
{"id":15, "url":"domain.com/path", "dm":"prefilled.com", "ip":"192.168.0.1"}

и мне нужно заменить «dm»: «-» на соответствующий домен из той же строки, чтобы получить этот вывод:

{"id":13, "url":"https://sub.domain.com/path", "dm":"sub.domain.com", "ip":"192.168.0.1"}
{"id":14, "url":"sub.domain2.com/?param=value", "dm":"sub.domain2.com", "ip":"192.168.0.1"}
{"id":15, "url":"domain.com/path", "dm":"prefilled.com", "ip":"192.168.0.1"}

с любыми командами bash только для строк, содержащих «dm»: «-» оптимизированным способом, так как файлы имеют длину более 10 тыс. строк

10.05.2017

  • Вы изучали использование jq ? 10.05.2017
  • Я изучаю это сейчас. Я отредактировал вопрос, чтобы отразить, что файл представляет собой журнал событий json, по одному в строке. 10.05.2017

Ответы:


1

С GNU или OSX для поддержки ERE через -E:

$ sed -E 's#(.*"url":"([^"]+\/\/)?([^"/]+).*"dm":")-"#\1\3"#' file
{"id":13, "url":"https://sub.domain.com/path", "dm":"sub.domain.com", "ip":"192.168.0.1"}
{"id":14, "url":"sub.domain2.com/?param=value", "dm":"sub.domain2.com", "ip":"192.168.0.1"}
{"id":15, "url":"domain.com/path", "dm":"domain.com", "ip":"192.168.0.1"}

С GNU awk для третьего аргумента для соответствия():

$ awk 'match($0,/(.*"url":"([^"]+\/\/)?([^"/]+).*"dm":")-(".*)/,a){$0=a[1] a[3] a[4]} 1' file
{"id":13, "url":"https://sub.domain.com/path", "dm":"sub.domain.com", "ip":"192.168.0.1"}
{"id":14, "url":"sub.domain2.com/?param=value", "dm":"sub.domain2.com", "ip":"192.168.0.1"}
{"id":15, "url":"domain.com/path", "dm":"domain.com", "ip":"192.168.0.1"}
10.05.2017
  • это работает! Однако один вопрос, как это сделать только для строк, в которых есть dm:- ? 10.05.2017
  • Спасибо за Вашу поддержку. Я отредактировал вопрос, чтобы отразить принятый ответ. 10.05.2017
  • Работает. Плюс один для парня, который многому научил меня о awk (в надежде, что когда-нибудь вам понравится jq так же сильно, как и мне ;)) 11.05.2017
  • Спасибо! До сих пор я лично не сталкивался с чем-то в json, что мне нужно проанализировать из командной строки, но я уверен, что когда-нибудь..... конечно, к тому времени, надеюсь, для него будет библиотека gawk :- ). 11.05.2017

  • 2

    С jq-1.5 (самая последняя версия atm) вы можете сделать:

    jq 'if .dm == "-" then .dm = (.url|sub("https?://";"")|sub("/.*";"")) else . end' a.json
    

    Объяснение:

    if .dm == "-" ...           # Runs the following only if .dm exists and it's value is "-"
    .dm=(...)                   # Assigns to .dm
    .url|sub("^https?://"; "")  # Takes .url and replaces http/https:// from the beginning
    ...|sub("/.*"; "")          # Replaces everything after the first / (including it)
    
    10.05.2017
  • Похоже, у ОП было скрытое требование, см. его комментарий в разделе мой ответ: how to do it only for the lines which have "dm":"-". Как это выглядит с jq? 10.05.2017
  • Просто ищу хороший способ с jq. На самом деле я собирался порекомендовать Python, который является самым чистым подходом к терминалу Linux. Дай мне немного времени. 10.05.2017
  • Хорошо, мне действительно интересно посмотреть, как jq справится с этим. 10.05.2017
  • Я думаю, что-то вроде этого: jq 'map(select(.dm == -) | .dm = (.url|sub(^https?://;)|sub(/.*;)))' a. json 10.05.2017
  • @Jinxmcg Похоже, вам не нужна помощь, так как у вас хорошие навыки jq! :) .. Почти правильно, но должно быть jq 'if .dm == "-" then .dm = (.url|sub("https?://";"")|sub("/.*";"")) else . end' 10.05.2017
  • @EdMorton ^^^^ смотри, здесь 10.05.2017
  • Я не знал о jq до публикации этого вопроса... :( кажется, это отличный инструмент, который я обязательно буду использовать в будущем. 10.05.2017
  • @Jinxmcg: Если вы хотите работать с данными json в командной строке, ответ всегда должен включать jq, он был разработан для этого. 10.05.2017

  • 3

    Вы можете использовать sed для этого, но я бы посоветовал вам использовать что-то, что действительно понимает данные, если есть какие-либо изменения в формате:

    sed -i -r 's/^(.*"url":")(.*\/\/)?(.*)(\/.*)"-"/\1\2\3\4"\3"/g' your_file
    
    10.05.2017
  • Что означает .*?? Если это предназначено для осмотра, sed их не поддерживает. 10.05.2017
  • sed с расширенным флагом регулярного выражения должен поддерживать нежадное сопоставление. Только что протестировал его, и он работает так, как ожидалось. 10.05.2017
  • Нет, нежадное сопоставление не является частью ERE, это часть PCRE, которую не поддерживает sed. Если вы получаете ожидаемый результат, то это по какой-то другой причине. 10.05.2017
  • Говорил слишком рано... Вы правы, но для рассматриваемого содержимого файла будет работать жадное сопоставление. 10.05.2017
  • Новые материалы

    Декларативное и функциональное программирование в стиле LINQ с использованием JavaScript с использованием каррирования и генератора ...
    LINQ - одна из лучших функций C #, которая обеспечивает элегантный способ написания кода декларативного и функционального стиля, который легко читать и понимать. Благодаря таким функциям ES6,..

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..

    Как я опубликовал свое первое приложение в App Store в 13 лет
    Как все началось Все началось три года назад летом после моего четвертого класса в начальной школе. Для меня, четвертого класса, лето кажется бесконечным, пока оно не закончится, и мой отец..

    Что в лицо
    Очерк о возвращении физиогномики и о том, почему мы должны это приветствовать. История начинается со странной науки. Р. Тора Бьорнсдоттир, Николас О. Рул. Видимость социального класса по..

    Почему шаблоны проектирования и почему нет?
    Сложность — мать всех проблем в программировании. Программное обеспечение должно быть разработано с точки зрения того, кто его поддерживает, а не того, кто его пишет, потому что программное..

    Создание дизайна обуви с помощью машинного обучения
    Обувь. Что подождать? Я думал, что речь пойдет о машинном обучении! Ну это так. Если бы вы пошли на Amazon, сколько обуви вы бы нашли? Наверное, много, не так ли? Но много ли в них..

    GraalVM в 2022 году: итоги года
    2022 год был очень продуктивным для проекта и сообщества GraalVM. Вместе мы разработали множество новых функций, выпустили GraalVM для последних версий Java и новых платформ и увидели несколько..