Nano Hash - криптовалюты, майнинг, программирование

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

У меня есть много файлов в формате двух столбцов с меткой в ​​​​первом столбце и номером во втором столбце. Число положительное (никогда не равно нулю):

AGS    3
KET    45
WEGWET    12
FEW    56

В каждом файле метки не повторяются.

Я хотел бы объединить эти многие файлы в один файл со многими +1 столбцами, чтобы первый столбец включал уникальный набор всех меток для всех файлов, а последние пять столбцов включали число для каждой метки каждого файла. Если метка не существовала в определенном файле (и, следовательно, для нее нет номера), я бы хотел, чтобы по умолчанию она была равна нулю. Например, если второй файл содержит это:

AGS    5
KET    14
KJV    2
FEW    3

то окончательный вывод будет выглядеть так:

AGS    3    5
KET    45   14
WEGWET    12    0
KJV    0    2
FEW    56    3

Я новичок в Linux и играл с sed и awk, но понимаю, что это, вероятно, требует нескольких шагов...

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

05.05.2014

Ответы:


1

Предполагая, что ваши данные находятся в файлах с именами file1 и file2:

$ awk 'FNR==NR {a[$1]=$2; b[$1]=0; next} {a[$1]+=0; b[$1]=$2} END{for (x in b) {printf "%-15s%3s%3s\n",x,a[x],b[x]}}' file1 file2
KJV      0  2
WEGWET  12  0
KET     45 14
AGS      3  5
FEW     56  3

Чтобы понять вышеизложенное, мы должны понять awk трюк. В awk NR — это количество записей (строк), которые были обработаны, а FNR — это количество записей, которые мы обработали в текущем файле. Следовательно, условие FNR==NR выполняется только при обработке в первом файле. В этом случае ассоциативный массив a получает все значения из первого файла, а ассоциативный массив b получает заполнители, т. е. нулевые значения. Когда мы обрабатываем второй файл, его значения попадают в массив b, и мы удостоверяемся, что массив a имеет по крайней мере нулевое значение заполнителя. Когда мы закончим со вторым файлом, данные будут напечатаны.

Более двух файлов с использованием GNU Awk

Я создал файл3:

$ cat file3
AGS    3
KET    45
WEGWET    12
FEW    56
AGS 17
ABC 100

Программа awk, расширенная для работы с любым количеством файлов:

$ awk 'FNR==1 {n+=1} {a[$1][n]=$2} END{for (x in a) {printf "%-15s",x; for (i=1;i<=n;i++) {printf "%5s",a[x][i]};print ""}}' file1 file2 file3
KJV             2     
ABC                100
WEGWET    12        12
KET       45   14   45
AGS        3    5   17
FEW       56    3   56

Этот код работает, создает счетчик файлов. Мы знаем, что находимся в новом файле каждый раз, когда FNR равно 1, а счетчик n увеличивается. Для каждой строки, с которой мы сталкиваемся, мы помещаем данные в двумерный массив. Первое измерение a — это метка, а второе — номер файла, в котором мы с ним столкнулись. В конце мы просто перебираем все метки и все файлы, от 1 до n, и печатаем данные.

Более 2 файлов без GNU Awk

Не требуя GNU awk, мы можем решить проблему, используя смоделированные двумерные массивы:

$ awk 'FNR==1 {n+=1} {b[$1]=1; a[$1,":",n]=$2} END{for (x in b) {printf "%-15s",x; for (i=1;i<=n;i++) {q=a[x,":",i]+0; printf "%5s",q};print ""}}' file1 file2 file3
KJV                0    2    0
ABC                0    0  100
WEGWET            12    0   12
KET               45   14   45
AGS                3    5   17
FEW               56    3   56
05.05.2014
  • Будет ли это работать для ›2 файлов? Где я бы просто изменил конечную часть с файл1 файл2 на файл1 файл2 файл3 файл4 файл5 файл6 05.05.2014
  • О, я только что прочитал вашу полезную заметку под кодом. Почему-то раньше не видел. Спасибо!! 05.05.2014
  • Да, я думаю, это работает только для двух файлов. Извините, я не уточнил, что у меня было больше, чем это... 05.05.2014
  • Большое спасибо. Но я получаю сообщение об ошибке: awk: синтаксическая ошибка в исходной строке 1, контекст FNR==1 {n+=1} ››› {a[$1][ ‹‹‹ awk: недопустимый оператор в исходной строке 1 awk: недопустимый оператор в исходная строка 1 05.05.2014
  • Я просто скопировал строку из ответа в шелл и у меня работает (linux, GNU awk). Вы на какой ОС? 05.05.2014
  • Я не уверен, может ли это быть проблемой, но метка первого столбца может быть длинной (например, до 12 символов) и включать как цифры, буквы и другие символы... 05.05.2014
  • @ user3603093 Хорошо. Я обновил его для широких этикеток. 05.05.2014
  • Это выглядит так здорово! Спасибо ... Другое дело, что я хотел, чтобы по умолчанию он был равен нулю, если в этом конкретном файле не было счетчиков. (Чтобы в каждом столбце каждой строки было хотя бы одно значение). 05.05.2014
  • Из того, что я получаю на выходе, в тех столбцах, у которых не было номера, просто не печатается значение. 05.05.2014
  • @user3603093 user3603093 Хорошо, я только что добавил нули в решение для Mac. 05.05.2014

  • 2

    Вот один из способов использования awk:

    awk '
    NR==FNR {a[$1]=$0;next}
    {
        print (($1 in a)?a[$1] FS $2: $1 FS "0" FS $2)
        delete a[$1]
    }
    END{
        for (x in a) print a[x],"0"
    }' file1 file2 | column -t
    AGS     3   5
    KET     45  14
    KJV     0   2
    FEW     56  3
    WEGWET  12  0
    
    • Вы читаете файл1 в массиве, проиндексированном в столбце 1, и назначаете всю строку в качестве значения
    • Для файла2 проверьте, присутствует ли столбец 1 в нашем массиве. Если это напечатать значение из файла1 вместе со значением из файла2. Если его нет, выведите 0 как значение для файла1.
    • Удалите элемент массива по мере продвижения, чтобы получить только то, что было уникальным в файле1.
    • В блоке END выведите то, что было уникальным в файле1, и выведите 0 для файла2.
    • Направьте вывод на column -t для красивого формата.
    05.05.2014
  • Спасибо большое! Как вы думаете, это будет работать для нескольких файлов? Чтобы я мог просто изменить эту часть file1 file2 | столбец -t в файл1 файл2 файл3 файл4 файл5 файл6 | столбец -т 05.05.2014
  • Извините, что я забыл упомянуть, что это более 2 файлов. Я просто использовал 2 в качестве примера, чтобы упростить вывод примера здесь... :o) 05.05.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..