Утилита UNIX 'comm' учитывает регистронезависимость в BSD, но не в Linux (с помощью флага -i). Как я могу получить это в Linux? - PullRequest
3 голосов
/ 28 января 2010

Я использую отличную утилиту командной строки UNIX 'comm' в приложении, которое я разработал на платформе BSD (OSX). При развертывании на моем производственном сервере Linux я обнаружил, что, к сожалению, утилита comm в Ubuntu Linux не принимает флаг -i, чтобы указать, что строки должны сравниваться без учета регистра. Очевидно, стандарт POSIX не требует опции -i.

Итак ... я в безвыходном положении. Мне действительно нужна опция -i, которая так хорошо работает на BSD. Я зашел так далеко, чтобы попытаться скомпилировать исходный код BSD comm.c для Linux, но получил:

http://svn.freebsd.org/viewvc/base/user/luigi/ipfw3-head/usr.bin/comm/comm.c?view=markup&pathrev=200559

me@host:~$ gcc comm.c 
comm.c: In function ‘getline’:
comm.c:195: warning: assignment makes pointer from integer without a cast
comm.c: In function ‘wcsicoll’:
comm.c:264: warning: assignment makes pointer from integer without a cast
comm.c:270: warning: assignment makes pointer from integer without a cast
/tmp/ccrvPbfz.o: In function `getline':
comm.c:(.text+0x421): undefined reference to `reallocf'
/tmp/ccrvPbfz.o: In function `wcsicoll':
comm.c:(.text+0x691): undefined reference to `reallocf'
comm.c:(.text+0x6ef): undefined reference to `reallocf'
collect2: ld returned 1 exit status

У кого-нибудь есть предложения, как получить версию comm для Linux, которая поддерживает 'comm -i'?

Спасибо!

Ответы [ 4 ]

1 голос
/ 28 января 2010

@ OP, нет необходимости идти на такую ​​длину, чтобы сделать свою собственную src-компиляцию. Вот альтернативное предложение. Поскольку вы хотите, чтобы регистр не учитывался, вы можете просто преобразовать регистры в обоих файлах в нижний (или верхний регистр), используя другой инструмент, такой как tr, прежде чем передавать файлы в comm.

tr '[A-Z]' '[a-z]' <file1 > temp1
tr '[A-Z]' '[a-z]' <file2 > temp2
comm temp1 temp2
1 голос
/ 28 января 2010

Вы можете добавить следующее в comm.c:

void *reallocf(void *ptr, size_t size)
{
    void *ret = realloc(ptr, size);
    if (ret == NULL) {
        free(ptr);
    }
    return ret;
}

Тогда вы сможете его скомпилировать. Убедитесь, что comm.c содержит #include <stdlib.h> (возможно, это уже сделано).

Причина неудачной компиляции в том, что BSD comm.c использует reallocf(), которая не является стандартной функцией C. Но это легко написать.

0 голосов
/ 26 февраля 2010

Вы можете попробовать перехватить оба файла и передать их по адресу uniq -c -i. Он покажет все строки в обоих файлах с количеством появлений в первом столбце. Пока исходные файлы не имеют повторяющихся строк, все строки с первым столбцом> 1 являются общими для обоих файлов.

Надеюсь, это поможет!

0 голосов
/ 28 января 2010

У кого-нибудь есть предложения, как получить версию comm в Linux, которая поддерживает 'comm -i'?

Не совсем так; но проверяли ли вы, чтобы ваши требования могли быть удовлетворены утилитой join? Этот имеет опцию -i в Linux ...

...