Сценарий оболочки для объединения двух файлов


8

Я хочу написать, shell scriptчто получить два файла Aи B, и получить результат, как это:

Файл A:

user_a tel_a addr_a
user_b tel_b addr_b

Файл B:

process_1 user_a
process_2 user_a
process_3 user_b

И результат:

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

Как я могу это сделать? awkили что-то другое?


2
Я думаю, что это может быть сделано с помощью cutи pasteтолько, но я не понимаю синтакс правильно.
Бернхард

Мои файлы имеют много записей и полей, я не могу вырезать и вставить! Это всего лишь образец.
Навид Фархади

1
@NavidFarhadi not cut & paste: есть две фактические команды cutи pasteпосмотрите на их страницу руководства.
Маттео

Я могу загрузить оба файла в память полностью, и я также могу использовать awk.
Навид Фархади

Я также могу использовать Perl или другие, если они были исполняемыми в командной строке Linux.
Навид Фархади

Ответы:


15

join ...

join -1 2 -2 1 FileB FileA

Вывод

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

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

join -1 2 -2 1 <(sort -k2 FileB) <(sort FileA)

Что значит числовые параметры?
Навид Фархади

5
@Navid: Вы всегда можете получить лучшее и наиболее точное описание параметров команды, обратившись к руководству , введя man joinв командной строке терминала ... -1 2   -2 1 означает: присоединиться к «1-му файлу, 2-му полю» и « 2nd-file 1st-field '
Peter.O

3

Так joinи pasteне везде (они не на моей BusyBox основе системы, например), вот как это сделать с AWK, в соответствии с просьбой:

awk 'BEGIN {
    while( (getline < "fileA") > 0) A[$1]=$2 OFS $3 # read fileA into the array A
    close("fileA")
  } {
    print $2, $1, A[$2]
  }' fileB

Кстати, вы пропустили разделитель A[$1]=$2 OFS $3... Вот еще один вариант, который избегает ручного цикла в BEGIN, но это почти то же самое (к awk ), хотя он вводит ненужный тест условия для второго файла: awk 'NR==FNR {A[$1]=$2 OFS $3;next} {print $2, $1, A[$2]}' fileA fileB... (+ 1)
Peter.O
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.