join: “O arquivo 2 não está na ordem classificada”

13

Eu tenho dois arquivos _jeter3.txt e _jeter1.txt

Eu verifiquei que ambos estão classificados na coluna 20 usando sort -c

sort -t '     ' -c -k20,20 _jeter3.txt
sort -t '     ' -c -k20,20 _jeter1.txt
#no errors

mas há um erro quando eu quero os joindois arquivos, ele diz que o segundo arquivo não está classificado:

join -t '   ' -1 20 -2 20 _jeter1.txt _jeter3.txt > /dev/null
join: File 2 is not in sorted order

Eu não entendo o porquê.

cat /etc/*-release #FYI
openSUSE 11.0 (i586)
VERSION = 11.0

UPDATE : usar ' sort -f' e join -i(sem distinção entre maiúsculas e minúsculas) corrige o problema. Mas isso não explica meu problema inicial.

UPDATE : versões de classificação e associação:

> join --version
join (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
(...)

> sort --version
sort (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
(...)
Pierre
fonte
Você pode nos dar a saída de "join --version" e "sort --version" apenas por uma questão de integridade? Não consigo obter algumas versões mais antigas do gnu join para me dar essa mensagem de erro sob nenhuma circunstância.
Bruce Ediger
3
Poste alguns dados de amostra que exibam o problema e a saída de locale.
Gilles 'SO- stop be evil'

Respostas:

25

Eu recebi o mesmo erro no Ubuntu 11.04, com sorte joinambos na versão (GNU coreutils) 8.5.

Eles são claramente incompatíveis. De fato, o sortcomando parece com erros: não há diferença com ou sem a opção -f( --ignore-case). Ao classificar, aaBé sempre antes aBa. Caracteres não alfanuméricos também parecem sempre ignorados ( abcantes ab-x)

Join parece esperar o oposto ... Mas eu tenho uma solução

Na verdade, esta está ligada à sequência de agrupamento: usando LANG=en_EN sort -k 1,1 <myfile> ..., em seguida, LANG=en_EN join ...elimina a mensagem.

A internacionalização é a raiz do mal ... (ninguém a documenta claramente).

Michael
fonte
Então, se os dois usarem LANG=en_EN, definitivamente funcionará? Funcionará para qualquer local, desde que ambos usem o mesmo local? Podemos dizer que a diferença entre sorte joiné que eles usam um código de idioma diferente por padrão?
Aaron McDaid
A -kopção é a resposta aqui ou é a LANG=en_EN? Não está claro qual é a solução exata aqui.
Utilizador
5

Você estava classificando com números? Eu descobri que o preenchimento zero da coluna na qual eu estava ingressando resolveu esse problema para mim.

cat file.txt \
     | awk -F"   " '{ $20=sprintf("%06s", $20); print $0}' \
     | sort > readytojoin.txt
Conor
fonte
5

Se você tiver certeza de que classificou corretamente seus arquivos de entrada e suas linhas podem ser emparelhadas, evite o erro acima executando join --nocheck-order file1.txt file2.txt

Yoav Weiss
fonte
4

sort por padrão, usa a linha inteira como a chave

join usa apenas o campo especificado como a chave.

Você deve corrigir essa incompatibilidade restringindo a classificação para usar apenas a chave na qual deseja ingressar.

A página do manual Join indica:

Importante: FILE1 e FILE2 devem ser classificados nos campos de junção. Por exemplo, use 'sort -k 1b, 1' se> 'join' não tiver opções. Observe que as comparações respeitam as regras especificadas por 'LC_COLLATE'. Se a entrada> não for classificada e algumas linhas não puderem ser unidas, uma mensagem de aviso será exibida.

PeterVermont
fonte
2
LOCALE=C sort ...
LOCALE=C join ...

Isto irá resolver o seu problema. O problema, como apontado por @Michael, é a sequência de intercalação, que depende da sua configuração LOCALE.

Jignesh Smart
fonte
2

Observe que se você vir esse erro e já tiver classificado em uma coluna específica e estiver batendo com a cabeça na parede, por exemplo, ordenar -k4,4, também poderá ser necessário definir o separador para o comando de ordenação

Aparentemente, o OP já fez isso com -t '', mas para um texto normal separado por tabulação eu recomendo

sort -t $'\t' ...

O comando de classificação pode incorporar espaços como separadores por padrão, mesmo em algo que se parece com um arquivo separado por tabulação (especialmente se houver espaços na coluna em que você está classificando).

Então, se você passou esses dados classificados para ingressar e você

join -t $'\t' ...

Então isso acaba causando a mensagem de erro sobre a falta de classificação. Como observado acima, a junção pode não aceitar -t ''.

Colin D
fonte
1

Para ingressar no argumento depois de -t é um caractere. Para classificação, você pode fornecer um separador de classificação mais longo. Eu acho que você pode estar juntando os arquivos em um campo diferente que você deseja, e ignorar o caso resolve o problema por coincidência.

E eu concordo com Gilles, que dados de amostra seriam úteis.

Paweł Brodacki
fonte