Как я могу (безболезненно) разделить или изменить порядок “Фамилия, Имя” в записи в Miller?

Вопрос или проблема

У меня есть файл, разделенный табуляцией, где один из столбцов имеет формат “Фамилия, Имя”. Я хотел бы разделить эту запись на два отдельных столбца, фамилия и имя, использовать cut или какие-то другие команды для этого и вывести результат в формате JSON.

Я должен добавить, что не привязан к JSON, и я знаю, как использовать другие инструменты, такие как jq, но было бы неплохо получить это в таком формате за один шаг.

Синтаксис для глагола nest выглядит так, будто необходимо запомнить множество, честно говоря, не запоминающихся опций, поэтому мне показалось, что должна быть простая DSL операция для выполнения этой задачи. Может быть, это не так?

Вот что я пробовал. (Давайте просто забудем о лишнем пробеле, который прикреплен к Имя прямо сейчас, ладно? Я бы использовал strip или ssub или что-то подобное, чтобы избавиться от него позже.)

echo -e "last_first\nLastName, Firstname" \
  | mlr --t2j put '$o=splitnv($last_first,",")'

# результат:
# { "last_first": "LastName, Firstname", "o": "(ошибка)" }

# ожидалось что-то вроде:
# { "last_first": "LastName, Firstname", "o": { 1: "LastName", 2: "Firstname" } }
#
# или:
# { "last_first": "LastName, Firstname", "o": [ "LastName", "Firstname" ] }

Почему (ошибка)? Не разумно ли полагать, что назначение $o, как указано выше, присвоит новую колонку o результату splitnv?

Вот что-то еще, что я пробовал, но тоже не сработало, как я ожидал:

echo -e "last_first\nLastName, Firstname" \
  | mlr -T nest --explode --values --across-fields --nested-fs , -f last_first

# результат (без разделителя здесь, только одно поле, подтверждено с помощью 'cat -A')
# last_first
# LastName, Firstname

# ожидалось:
# last_first_1<tab>last_first_2
# LastName,<tab> Firstname

Редактирование: Проблема с командой выше в том, что я должен был использовать --tsv, а не -T, что является синонимом --nidx --fs tab (числовых индексов столбцов). Проблема в том, что Miller не выдает сообщение об ошибке, когда явно неправильно запрашивать именованные столбцы в этом случае, что может быть недостатком; см. вопрос #233.

Любая информация будет принята с благодарностью.

Я не знаю, правильно ли я понимаю ваш запрос.

Если я выполняю

echo -e "last_first\nLastName, Firstname" | \
mlr --t2j --jlistwrap --jvstack nest --explode --values --across-fields --nested-fs "," -f last_first \
then clean-whitespace

У меня получается

[
{
  "last_first_1": "LastName",
  "last_first_2": "Firstname"
}
]

И если я выполняю

echo -e "last_first\nLastName, Firstname" | \
mlr --tsv nest --explode --values --across-fields --nested-fs "," -f last_first \
then clean-whitespace

Я получаю

last_first_1    last_first_2
LastName        Firstname

Вот как переключить LastName, FirstName на FirstName LastName с помощью выражений DSL:

echo -e "last_first\nLastName, Firstname\nAnotherLast, AnotherFirst" \
  | mlr --t2j \
    put -q 'o=splitnv($last_first,",");
            first_last=strip(o[2]) . " " . o[1];
            emit first_last'

# результат:
# { "first_last": "Firstname LastName" }
# { "first_last": "AnotherFirst AnotherLast" }

Я думаю, что факт, что emit оказывается необходимым(?), был ключевой частью, которую я не понимал раньше.

К сожалению, это не намного проще, чем использование глагола nest и всех его необходимых флагов.

С более актуальной версией Miller, ваша команда mlr --t2j put '$o=splitnv($last_first,",")' генерирует

[
{
  "last_first": "LastName, Firstname",
  "o": {
    "1": "LastName",
    "2": " Firstname"
  }
}
]

… в то время как использование splita() генерировало бы

[
{
  "last_first": "LastName, Firstname",
  "o": ["LastName", " Firstname"]
}
]

Предполагая, что поле last_first всегда содержит одну запятую…

С

put '$last_first = splita($last_first,",")'

… мы заменяем данное строковое поле last_first на массив, содержащий начальные пробелы во втором элементе:

+--------------+--------------+
| last_first.1 | last_first.2 |
+--------------+--------------+
| LastName     |  Firstname   |
+--------------+--------------+

Мы можем flatten этот массив и использовать clean-whitespace, чтобы избавиться от пробелов:

put '$last_first = splita($last_first,",") then \
flatten then \
clean-whitespace

Чтобы получить результат, переименуйте поля:

put '$last_first = splita($last_first,",")' then \
flatten then \
clean-whitespace then \
label last,first

Это дает нам

+----------+-----------+
| last     | first     |
+----------+-----------+
| LastName | Firstname |
+----------+-----------+

Ответ или решение

Чтобы решить проблему, описанную вами, необходимо использовать инструмент Miller (mlr) для изменения формата данных в табличном файле, где одно из полей формата "LastName, FirstName". Задача заключается в том, чтобы разделить это поле на два отдельных столбца last и first, а затем экспортировать результат в JSON-формате. Давайте рассмотрим подход к решению этой задачи более детально, следуя методу TEA (Теория, Пример, Применение).

Теория

Miller (mlr) – это мощный инструмент командной строки, который позволяет обрабатывать данные из файлов в формате CSV, JSON и многих других. Он известен своей способностью быстро и эффективно обрабатывать данные и предоставлять возможности для выполнения различных трансформаций и анализов.

Для вашей задачи нам нужно использовать функцию split для разделения строки по определенному разделителю (в данном случае – запятая) и манипулировать данными так, чтобы получить нужный вывод. Специфика системы Miller позволяет нам использовать сценарии на встроенном языке для выполнения более сложных операций с данными.

Пример

Прежде чем мы перейдем к тому, как применять это на практике, приведем пример выполнения этих шагов:

  1. Входные данные:

    last_first
    LastName, Firstname
  2. Способ применения:

    Вы можете использовать следующее сочетание команд Miller для достижения цели разделения имени и фамилии:

    echo -e "last_first\nLastName, Firstname" \
     | mlr --t2j put '$last_first = splita($last_first, ",")' then \
     flatten then \
     clean-whitespace then \
     label last, first
  3. Результат формата JSON:

    Для вывода в формате JSON, вы можете выполнить:

    echo -e "last_first\nLastName, Firstname" \
     | mlr --t2j --jlistwrap --jvstack put '$last_first = splita($last_first, ",")' then \
     flatten then \
     clean-whitespace then \
     label last, first

    Это создаст JSON-вывод следующего вида:

    [
     {
       "last": "LastName",
       "first": "Firstname"
     }
    ]

Применение

Понимание синтаксиса и как применять функции в Miller является ключевым моментом для выполнения этой задачи. Использование команд splita и flatten в совместимости с другими утилитами Miller позволяют эффективно разделить и обработать текстовые строки.

  1. Функция splita: Она используется для разделения строки на массив, основываясь на заданном разделителе. Это полезно, когда нам нужно разделить имени и фамилии, используя запятую в качестве разделителя.

  2. Функция flatten: После разделения строки мы получаем массив, который нужно преобразовать обратно в простые столбцы для дальнейшей обработки.

  3. Функция clean-whitespace: Она устраняет лишние пробелы в строках, которые могли быть оставлены после операции разделения.

  4. Команда label: Позволяет нам переименовать полученные поля массива в более понятные last и first.

Следуя этим шагам, можно настроить обработку даже более сложных наборов данных, расширяя использование Miller для различных форма🔥тов данных и более сложных трансформаций. Например, вы можете настроить вывод на работу с другими формами экспорта или добавлять дополнительные этапы обработки данных, такие как фильтрация или агрегирование информации по специфическим требованиям вашего рабочего процесса.

Для выполнения операции преобразования полей в формат FirstName LastName, вы можете использовать следующий подход:

echo -e "last_first\nLastName, Firstname" \
  | mlr --t2j \
    put 'o=splitnv($last_first,",");
         first_last=strip(o[2]) . " " . o[1];
         emit first_last'

Данный подход не только показывает гибкость и универсальность Miller, но и позволяет легко адаптировать его под различные форматы и требования к итоговому результату.

Оцените материал
Добавить комментарий

Капча загружается...