Обновление: Вопрос был отредактирован так, что все файлы содержат все ключи, поэтому принятый ответ (join
) определенно лучше, чем этот. Используйте только этот вариант, если возможно, что ключи могут быть не во всех файлах.
Если вы не слишком обеспокоены производительностью, вы можете попробовать быстрое и грязное:
$ cat file_a
ID5 Value5a
ID1 Value1a
ID3 Value3a
ID4 Value4a
ID2 Value2a
$ cat file_b
ID1 Value1b
ID3 Value3b
$ cat file_c
ID2 Value2c
ID3 Value3c
ID4 Value4c
ID5 Value5c
$ cat qq.sh
#!/bin/bash
keylist=$(awk '{print $1'} file_[abc] | sort | uniq)
for key in ${keylist} ; do
val_a=$(grep "^${key} " file_a | awk '{print $2}') ; val_a=${val_a:--}
val_b=$(grep "^${key} " file_b | awk '{print $2}') ; val_b=${val_b:--}
val_c=$(grep "^${key} " file_c | awk '{print $2}') ; val_c=${val_c:--}
echo ${key} ${val_a} ${val_b} ${val_c}
done
$ ./qq.sh
ID1 Value1a Value1b -
ID2 Value2a - Value2c
ID3 Value3a Value3b Value3c
ID4 Value4a - Value4c
ID5 Value5a - Value5c
Это на самом деле сначала работает с ключами, затем получает значения из каждого файла с этим ключом, или -
, если его нет в соответствующем файле.
Команды grep
необходимо будет скорректировать, если файл более сложный (либо если поле 1 находится не в начале строки, либо за ним следует разделитель без пробела), но сначала это должно быть разумным решение Вероятность использования grep
в этом случае будет:
grep "^[ X]*${key}[ X]"
, где X
на самом деле является символом tab , так как это позволяет использовать пробелы или табуляции ноль или более перед клавишей и пробел или табуляцию для завершения клавиши.
Если файлы особенно велики, вы можете захотеть использовать ассоциативные массивы в пределах awk
, но, поскольку нет указания на размер, я начну с этого, пока вы не дойдете до точки, где он работает слишком медленно.