Por que o sed não está fazendo o que está definido no arquivo de agrupamento de localidade para grep (e sed, awk)?

Por que o sed não está fazendo o que está definido no arquivo de agrupamento de localidade para grep (e sed, awk)?

Ter um arquivo com todos os caracteres ascii (imprimíveis):

$ printf '%b' "$(printf '\\U%x\n' {32..126})" > file

Isso poderia ser classificado (usando tr para reduzir a saída longa para uma linha):

$ sort file | tr -d '\n'
 !"#%&'()*+,-./:;<=>?@[\]^_`{|}~$0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ

Mostra que em um computador Debian buster usando um locale en_US.utf8 a classificação agrupada (para caracteres únicos) tem primeiro toda a pontuação, depois os números e depois as letras maiúsculas misturadas. Ou seja: aAbB, letras maiúsculas e minúsculas juntas.

Vamos supor que isso esteja correto e é o que o usuário (Eu) deseja que aconteça para o agrupamento.

Porém, no mesmo sistema, sem nenhuma outra alteração, acontece isso:

$ grep '[a-z]' file | tr -d '\n'
abcdefghijklmnopqrstuvwxyz

Esse intervalo a-zé traduzido por algo apenas para letras ASCII minúsculas.

Quem está fazendo a tradução e como isso pode ser controlado ou alterado?

Não estou perguntando o que são letras minúsculas, nem o que [az] deveria significar ou alguém deseja que isso signifique.

Espero que [a-z]seja um intervalo que começa ae termina emz na ordem de agrupamento.

Entendo que alguns outros usuários desejam que a [a-z]média seja igual a "minúsculas" em qualquer localidade. E eu poderia “conviver com isso” por padrão.

Mas como eu poderia controlar e/ou mudar isso, se necessário? Onde está o botão para mudar isso?

Não, alterar os arquivos agrupados não ajuda, algo está acima e além disso e reforça a visão pessoal de que [a-z]deve significar letras ASCII minúsculas o tempo todo em todas as localidades.

Responder1

eu li o queEstados POSIX. Minha interpretação é que existem dois conceitos não equivalentes:

  • sequência de agrupamento (sequência de agrupamento)
  • ordem de agrupamento

Fragmentos relevantes [ênfase minha]:

A LC_COLLATEcategoria oferecesequência de agrupamentodefinição para vários utilitários no volume Shell e Utilitários do POSIX.1-2017 ( ls, sort, e assim por diante), correspondência de expressões regulares (consulte Expressões regulares) e as funções strcoll(), strxfrm(), e no volume Interfaces do sistema do POSIX.1- 2017.wcscoll()wcsxfrm()

Asequência de agrupamentodefinição deve definir a ordem relativa entre os elementos de agrupamento (caracteres e elementos de agrupamento de vários caracteres) no código do idioma. Esta ordem é expressa em termos de valores de ordenação; isto é, atribuindo a cada elemento um ou mais valores de agrupamento (também conhecidos como pesos de agrupamento). […]

A order_startpalavra-chave deve precederordem de agrupamentoentradas e também definir o número de pesos para estesequência de agrupamentodefinição e outras regras de agrupamento.

Oordem de agrupamentoconforme definido nesta seção afeta a interpretação de expressões entre colchetes em expressões regulares (consulte RE Expressão entre colchetes).

Para sorta sequência de agrupamento importa, ou seja, os pesos. Para grep '[a-z]'a ordem de ordenação é importante, ou seja, a ordem das entradas da ordem de ordenação.

Infelizmente, apenas a sequência de agrupamento édefinido explicitamente, portanto, não há indicação clara de que a ordem de agrupamento seja um conceito diferente.

Sequência de agrupamento
A ordem relativa de agrupamento de elementos, conforme determinado pela configuração da LC_COLLATEcategoria no código do idioma atual. A sequência de agrupamento é usada para classificação e é determinada a partir dos pesos de agrupamento atribuídos a cada elemento de agrupamento. Na ausência de pesos, a sequência de ordenação é a ordem na qual os elementos de ordenação são especificados entre as palavras-chave order_starte order_endna LC_COLLATEcategoria.


No meu Debian 9, quando se trata de LC_COLLATE, muitas localidades eventualmente se referem a iso14651_t1_common(ou seja /usr/share/i18n/locales/iso14651_t1_common, ). O fragmento relevante do arquivo é assim:

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U00AA> <a>;<PCL>;<EMI>;IGNORE # 199 ª
<U00E1> <a>;<ACA>;<MIN>;IGNORE # 200 á
[…]
<U0062> <b>;<BAS>;<MIN>;IGNORE # 233 b
<U0253> <b>;<CRL>;<MIN>;IGNORE # 234 ɓ
<U1E03> <b>;<PCT>;<MIN>;IGNORE # 235 ḃ
[…]
<U007A> <z>;<BAS>;<MIN>;IGNORE # 507 z
<U017A> <z>;<ACA>;<MIN>;IGNORE # 508 <z'>
<U017E> <z>;<CAR>;<MIN>;IGNORE # 509 <z<>
[…]
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A
<U00C1> <a>;<ACA>;<CAP>;IGNORE # 518 Á
<U00C0> <a>;<GRA>;<CAP>;IGNORE # 519 À
[…]
<U0042> <b>;<BAS>;<CAP>;IGNORE # 550 B
<U1E02> <b>;<PCT>;<CAP>;IGNORE # 551 <B.>
<U1E04> <b>;<BPT>;<CAP>;IGNORE # 552 Ḅ
[…]
<U005A> <z>;<BAS>;<CAP>;IGNORE # 813 Z
<U0179> <z>;<ACA>;<CAP>;IGNORE # 814 <Z'>
<U017D> <z>;<CAR>;<CAP>;IGNORE # 815 <Z<>

Isto é oordem de agrupamento. [a-z]não contém Aporque a entrada para A( <U0041>) não está entre as entradas para ae z.

Ainda as entradas para ae Aespecificam o mesmo símbolo de agrupamento <a>. Da mesma forma be Bespecifique <b>. Isso se traduz em pesos:

Os pesos devem ser expressos como caracteres (em qualquer uma das formas especificadas na Definição de Localidade), <collating-symbol>s, <collating-element>s, reticências ou o símbolo especial IGNORE. Um único caractere, a <collating-symbol>ou a <collating-element>deve representar a posição relativa no caracteresequência de agrupamentodo personagem ou símbolo, em vez do próprio personagem ou personagens. Assim, em vez de atribuir valores absolutos aos pesos, um peso específico é expresso usando o valor da ordem relativa atribuído a um elemento de agrupamento com base na sua ordem no caracteresequência de agrupamento.

No arquivo <a>e <b>são definidos nesta ordem:

collating-symbol <a>
collating-symbol <b>

Isso torna a subsequência relevante desequência de agrupamentoser aAbB. Isto é o que importa sort.


Para confirmar isso, movi (temporariamente) a seguinte entrada do pedido de agrupamento

<U004B> <k>;<BAS>;<CAP>;IGNORE # 649 K

para uma posição imediatamente antes da entrada for v, ou seja, em algum lugar entre ae z. Eu reconstruí meus locais com locale-gen. Agora sort file | tr -d '\n'ainda retorna …iIjJkKlLmM…(os pesos não mudaram, a sequência de agrupamento não mudou), mas grep '[a-z]' file | tr -d '\n'produz:

Kabcdefghijklmnopqrstuvwxyz

Isso significa que pertenço Kalterando [a-z]a ordem de agrupamento.

Se você quiser grep '[a-z]' file | tr -d '\n'retornar uma permutação em aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZvez de abcdefghijklmnopqrstuvwxyz, será necessário usar uma localidade com ordem de agrupamento diferente. Pode ser uma localidade personalizada.

informação relacionada