Qual é a ordem de classificação ao usar operadores condicionais?

5

Eu escrevi um script bash que processa uma lista de nomes de arquivos (usando a expansão glob, como em for f in * ) e, em seguida, gera um subconjunto dessa lista para um arquivo. Subsequentemente, leio o conteúdo desse arquivo em uma matriz e executo uma pesquisa binária simples para nomes de arquivos específicos usando os óbvios operadores < e > para comparar strings.

Considerando que eu gostaria que o script trabalhasse em vários ambientes diferentes, como Linux, MacOS, MinGW, ... (mesmo usando coisas como [[ e stat , que são menos portáveis), minhas perguntas são :

  1. Preciso classificar o conteúdo do arquivo (com sort ou código bash adicional) ou a expansão glob é sempre classificada - em todos os ambientes?
  2. Os operadores condicionais usam a mesma "classificação" da expansão (ou depois de sort )?

    A expansão ou sort retornam file10.txt após file2.txt (em quais casos?), mas o uso de operadores condicionais file10.txt seria antes de file2.txt ? Qual sort opção eu usaria para corrigir isso?

  3. Existe algum aviso se alguns dos meus nomes de arquivos estão em Unicode?

  4. Existe algum problema ao usar versões específicas do bash?
  5. O LC_COLLATE afeta alguma das opções acima?

Eu obviamente preciso que o conteúdo do arquivo corresponda ao "método" de classificação dos operadores para que a pesquisa binária funcione como esperado ...

    
por Paolo 23.03.2016 / 10:43

1 resposta

2

Sim, a expansão glob é sempre classificada.
No bash (de LESS=+/'^ *Pathname Expansion' man bash )

Pathname Expansion ... the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.

Isso também é especificado pelo POSIX glob :

... The pathnames are in sort order as defined by the current setting of the LC_COLLATE category.

Note1 : a menos que o sinalizador GLOB_NOSORT esteja definido. Nesse caso, o pedido não é especificado.

Note2 : A ordem de classificação é alfabética (não numérica), 10 classifica antes de 2.

Respostas:

  1. Do I need to sort the file content (either with sort or additional bash code) ...

Globing não tem relação com o conteúdo do arquivo, só funciona com nomes de arquivos.
Se você precisar ordenar o "conteúdo do arquivo", então, sim, você precisa chamar sort de usar um pouco mais bash code.

  1. ... or is the glob expansion always sorted - in every environment?

A menos que seja desativado com GLOB_NOSORT , o resultado de Globing será classificado na ordem definida pela ordem de agrupamento (variável LC_COLLATE ) no ambiente.

Para ter a mesma ordem de classificação, você deve ter o mesmo agrupamento em vigor. Ambos definem uma variável LC_COLLATE e uma descrição locale que contém os mesmos detalhes de agrupamento.

  1. Do the conditional operators use the same "sorting" as the expansion (or after sort)?

Sim. Ambos são afetados da mesma maneira por LC_COLLATE .

  1. Would expansion or sort return file10.txt after file2.txt (in what cases?) but using conditional operators file10.txt would be before file2.txt ? What sort option would I use to fix this?

Um resultado de 10 antes de 2 é "ordem do dicionário", que é o mesmo que é chamado de "ordem alfabética" na descrição manual do bash. Então, se você usar bash (ou qualquer shell POSIX) para classificar, essa é a ordem que você obterá (em todos os casos). Isso não está errado, então não é solucionável (para texto).

No entanto, se você optar por usar sort (uma ferramenta externa, fora do shell), poderá solicitar numeric sort (a opção -n), que colocará 2 antes de 10 . Ou você pode extrair os números do texto e usá-los para fazer uma comparação de inteiros (os operadores -lt -gt integer) no shell.

Are there any caveats if some of my filenames are in Unicode?

Principalmente: A ordem de intercalação não é fixa.

Ele muda com o tempo e a versão UNICODE.

O que pode acontecer é que você obtenha resultados surpreendentes em algum idioma com o qual não está familiarizado. Por exemplo:

"aa" corresponderia "å" a um dinamarquês

Resumindo: »Esteja preparado para ser surpreendido«.

Are there any issues using specific versions of bash?

Bem, você deve usar uma versão bash acima de 2.0

respect LC_COLLATE  2.0 

Does LC_COLLATE affect any of the above?

A variável LC_COLLATE afeta todos dos itens acima.

    
por 25.03.2016 / 23:54