Самый простой способ объединить два файла из командной строки Unix, вставив нулевые записи для отсутствующих ключей - PullRequest
3 голосов
/ 26 октября 2011

Я пытаюсь объединить два файла, каждый из которых содержит строки вида <key> <count>.Каждый файл содержит несколько строк, которые отсутствуют в другом, и я хотел бы вставить ноль для всех таких значений, а не пропускать эти строки (я видел -a, но это не совсем то, что я ищу).Есть ли простой способ сделать это?

Вот несколько примеров ввода:

a.txt

apple 5
banana 7

b.txt

apple 6
cherry 4

ожидаемый результат:

apple 5 6
banana 7 0
cherry 0 4

Ответы [ 3 ]

11 голосов
/ 26 октября 2011
join -o 0,1.2,2.2 -e 0 -a1 -a2 a.txt b.txt
  • -o 0,1.2,2.2 → выходное поле соединения, затем 2-е поле 1-го файла, затем 2-е поле 2-го файла.
  • -e 0 → Вывести 0 в пустые поля ввода.
  • -a1 -a2 → Показать все значения из файла 1 и файла 2.
0 голосов
/ 26 октября 2011

@ ответ ninjalj гораздо более разумный, но вот реализация сценария оболочки просто для удовольствия:

exec 8< a.txt
exec 9< b.txt

while true; do
   if [ -z "$k1" ]; then
    read k1 v1 <& 8
   fi
   if [ -z "$k2" ]; then
    read k2 v2 <& 9
   fi
   if [ -z "$k1$k2" ]; then break; fi
   if [ "$k1" == "$k2" ]; then
    echo $k1 $v1 $v2 
    k1=
    k2=
   elif [ -n "$k1" -a "$k1" '<' "$k2" ]; then
    echo $k1 $v1 0 
    k1=
   else 
    echo $k2 0 $v2
    k2=
   fi
done
0 голосов
/ 26 октября 2011

Напишите скрипт на любом языке, который вы хотите.Вы проанализируете оба файла, используя структуру данных map / hashtable / dictionary (скажем, словарь).Каждый словарь будет иметь первое слово в качестве ключа и счетчик (или даже строка счетчиков) в качестве значения.Вот некоторый псевдокод алгоритма:

Dict fileA, fileB; //Already parsed
while(!fileA.isEmpty()) {
      string check = fileA.top().key();
      int val1 = fileA.top().value();
      if(fileB.contains(check)) {
          printToFile(check + " " + val1 + " " + fileB.getValue(check));
          fileB.remove(check);
      }
      else {
          printToFile(check + " " + val1 + " 0");
      }
      fileA.pop();
}
while(!fileB.isEmpty()) {      //Know key does not exist in FileA
     string check = fileB.top().key();
     int val1 = fileB.top().value();
     printToFile(check + " 0 " + val1);
     fileB.pop();
}

Вы можете использовать любой тип итератора для прохождения структуры данных вместо pop и top.Очевидно, вам может потребоваться доступ к данным по-разному, в зависимости от того, какой язык / структуру данных вам нужно использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...