Как объединить два файла, сопоставив два параметра с awk

why we don't add a key from the second repo, but only from the first one

Потому что у них одинаковый открытый ключ.

curl http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
curl https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub

why do we run sudo dpkg -i for the first.deb file and sudo apt install for the second?

В этом случаеdpkgи aptустановят только репозиторий, aptимеет тот же эффект, что и dpkg, потому что установка репозитория не требует установки каких-либо других зависимостей.

Обратите внимание, что aptможет разрешить зависимости, а dpkg— нет.

1
15.09.2020, 15:55
2 ответа

Первое решение с использованием GNU awk или POSIX awk

Редактировать:Как написал Эд Мортон в своем комментарии, первоначальный ответ был неверным относительно того, что поддерживается только GNU awk. (Формулировки в документации GNU и документации POSIX немного сбивают с толку.)

То, что документация GNU awkназывает многомерными массивами , поддерживается POSIX-совместимым awk. См.https://pubs.opengroup.org/onlinepubs/000095399/utilities/awk.htmlи найдите «многомерный -» или SUBSEP. Эти массивы на самом деле являются одномерными -.

GNU awkтакже поддерживает массивы массивов , которые являются реальными многомерными -массивами.

Эта версия команды требует GNUawk:

awk -F"\t" 'NR == FNR { a[$2][$4] = $5; next } { print $0, a[$2][$4] }' B.txt A.txt > C.txt

Совместимый с POSIX вариант (*), который должен работать с любым awk, — это

awk -F"\t" 'NR == FNR { a[$2,$4] = $5; next } { print $0, a[$2,$4] }' B.txt A.txt > C.txt

Оба печатают

Cycle   Well    Value   Target 
1   A1  5.07368111264623    EC Unkn-01
1   A1  3.06982862746599    FT Unkn-09
1   A1  2.46545646544623    EC Unkn-01

Данные из файла B.txtсохраняются в массив a, т.к. согласно вопросу ключ Скважина/Цель в этом файле уникален. Затем эти данные добавляются к данным из файла A.txt.

Разделитель полей должен быть указан явно. В противном случае awkбудет игнорировать пустые столбцы/значения.

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

Изменить:Следующее решение, которое явно объединяет выражения индекса с \tв качестве разделителя, не имеет преимуществ по сравнению с POSIX-совместимым решением (*), показанным выше.

awk -F"\t" 'NR == FNR { a[$2 "\t" $4] = $5; next } { print $0, a[$2 "\t" $4] }' B.txt A.txt > C.txt

Это эквивалентно настройке SUBSEP = "\t"и использованию синтаксиса a[$2, $4].


Второе решение с использованием q

Инструмент q можно использовать для выполнения запросов к базам данных в файлах CSV.

См.http://harelba.github.io/q/илиhttps://github.com/harelba/q

В этом решении есть проблема с пустым заголовком столбца в B.txt. В качестве обходного пути я добавил заголовок Emptyв строку заголовка этого файла.

Поэтому я использую эти файлы:

A.txt

Cycle   Well    Value   Target
1   A1  5.07368111264623    EC
1   A1  3.06982862746599    FT
1   A1  2.46545646544623    EC

B.txt

Empty   Well    Fluor   Target  Content Sample
    A1  Cy5 EC  Unkn-01 2060563935
    A1  Cy5 FT  Unkn-09 2156515156

Команда

q -H -t "select a.Cycle,a.Well,a.Value,a.Target,b.Content from A.txt as a inner join B.txt as b on a.Well=b.Well and a.Target=b.Target"

отпечатки

1   A1  5.07368111264623    EC  Unkn-01
1   A1  3.06982862746599    FT  Unkn-09
1   A1  2.46545646544623    EC  Unkn-01

Для печати заголовка вы можете добавить команду printfили echo.

printf "Cycle\tWell\tValue\tTarget\tContent\n" > C.txt
q -H -t "select a.Cycle,a.Well,a.Value,a.Target,b.Content from A.txt as a inner join B.txt as b on a.Well=b.Well and a.Target=b.Target" >> C.txt

Для автоматизации модификации файла B.txtвы можете использовать

printf "Empty" > B1.txt
cat B.txt >> B1.txt
printf "Cycle\tWell\tValue\tTarget\tContent\n" > C.txt
q -H -t "select a.Cycle,a.Well,a.Value,a.Target,b.Content from A.txt as a inner join B1.txt as b on a.Well=b.Well and a.Target=b.Target" >> C.txt

В этом решении использовались именованные столбцы из строки заголовка, чтобы определить столбцы для сопоставления или печати.

2
18.03.2021, 23:04

Предполагая, что у вас есть GNU awkдля двухмерных -массивов, следующая программа выполнит эту задачу:

awk -F'\t' 'NR==FNR&&FNR>1{map[$2][$4]=$5}\
            NR>FNR{if (FNR==1) {$5="Content"} else {$5=map[$2][$4]}} NR>FNR' B.txt A.txt > C.txt

Это сначала обработает B.txtдля создания отображения значений «Содержание» на конкретную комбинацию «Колодец» и «Цель». При обработке A.txtпосле (, обозначенной FNR, счетчик на -строку файла -теперь меньше, чем NR, глобальный счетчик строки -), программа ищет определенное сочетание «Колодец» и «Цель» на текущей строке и подставляет соответствующее значение «Содержимое» из карты, созданной ранее. Он печатает вывод только после обработки второго файла ("беспризорного" NR>FNRусловия ).

2
18.03.2021, 23:04

Теги

Похожие вопросы