Об’єднайте файли за допомогою загального стовпця


8

У мене є два файли, з яких я хочу створити третій, який містить всю інформацію.

файл 1:

a 111 
b 222 
c 333 
d 666 
e 777 

файл 2:

111 x1  
222 x2
333 x3
444 x4 
555 x5 
666 x6 
777 x7 
888 x8

Я хотів би поєднати їх у такий спосіб:

111  x1  a
222  x2  b
333  x3  c
444  x4  0
555  x5  0
666  x6  d
777  x7  e
888  x8  0

Примітка:

Другий стовпець файлу 1 - це підмножина першого стовпця файла 2

Відповіді:


7

joinКоманда робить майже те , що вам потрібно, якщо файли сортуються як в ваших зразках:

join -12 -a2 file1 file2 -o2.1,2.2,1.1

Вам потрібно просто додати нулі до рядків без збігу. Ви можете використовувати для цього -eперемикач:

join -12 -a2 file1 file2  -o2.1,2.2,1.1 -e0

якщо ви додасте -e0не потрібно perl :)
LilloX

@LilloX: Правда, дякую. Я намагався, але не вдалося (помилка друку).
choroba

13

Використання приєднання:

join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1

Команда join приєднується до рядків двох файлів, які мають спільне поле даних. У цьому випадку: Об’єднайте файл2 та файл1, використовуючи поле 1 ( -1 1) файлу2 та поле 2 ( -2 2) файлу1.

Виведенням буде: "з'єднане поле, поле 2 файлу2, поле 1 файлу1" ( -o'0,1.2,2.1'), якщо є поле, яке відсутнє, поставити 0 ( -e0)

Якщо один з двох файлів має більше записів, додайте їх (у цьому випадку file2) ( -a1)

Будь ласка, зверніться до сторінки сторінки команди приєднання


Добре. Чи можете ви додати трохи пояснень?
Леті

Звичайно, оновлено :)
LilloX

5

Трохи awkмагії:

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; \
    printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}' \
    file1 file2

або

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0};
    print $1,$2,a[$1]}' file1 file2

Вихідні дані

111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Пояснення

  • FNR==NR{a[$2]=$1;next}

    Переходить на file1( FNR==NR) і створює структуру ключа-значення. Ключ - другий стовпець ( $2) file1, значення - перший стовпець ( $1)file1

  • {if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}

    Перебігає над file2і

    • if(a[$1]==""){a[$1]=0}

      Якщо ключ у першому стовпці ( $1) в file2не існує в file1, нам потрібен а0

    • print $1,$2,a[$1]

      Роздрукуйте (використовуючи print) перший та другий стовпчик file2та значення структури ключ-значення за допомогою ключа першого стовпця ( $1)file2

      або

    • printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'

      Роздрукуйте (використовуючи printf) перший та другий стовпчик file2та значення структури ключ-значення за допомогою ключа першого стовпця ( $1) file2.

      • FS є роздільником між стовпцями, узятим із вхідного файлу

      • "%s%s%s%s%s\n"

        - форматування для виводу

        • %s - Рядок

        • \n - Новий рядок


Чи можете ви пояснити код?
gforce89

Звичайно, відповідь оновлена.
AB

1

Використання q :

$ q "select f2.c1, f2.c2, ifnull(f1.c1,0) from file_2.txt f2 LEFT JOIN file_1.txt f1 on f1.c2 = f2.c1 "
111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Іноді це може бути читабельніше.


1
Для всіх, хто цікавиться, qє в пакеті python3-q-text-as-data(Python 3) і в пакеті python-q-text-as-data(Python 2).
kos

Дякую, але де я можу отримати цей qпакет? Я, здається, не в змозі встановити або, python-q-text-as-dataабо python3-q-text-as-data. "E: Неможливо знайти пакет python3-q-text-as-data". Моя система вже встановлена python, python2.7, python3і python3.4.
Падді Ландау

Можливо, пакет занадто новий і він недоступний у вашій дистрибутивній версії. Ви можете його клонувати Github: github.com/harelba/q
Vi.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.