Укажите, что порядок сортировки с LC_COLLATE, так строчным, перед верхним регистром

rsync --verbose --archive --dry-run /oldisk/a/ /newdisk/a/

--dry-run (или -n) сделает пробный прогон, показывая Вам, что он обошелся бы без фактического выполнения чего-либо.

Если это смотрит хорошо, выполните rsync без -n опция.

Это будет копией, не перемещение, которое не является вполне, что Вы делаете, но более безопасно. --archive (или -a) гарантирует все владение и устанавливает метку времени, метаданные сохраняются (который обычная копия не была бы).

16
10.05.2013, 14:49
5 ответов

Я не знаю ни одной локали, которая по умолчанию сортирует в таком порядке. Решение состоит в том, чтобы создать пользовательскую локаль с настраиваемым порядком сортировки. Если кто-то четыре года спустя захочет отсортировать по индивидуальному заказу, вот хитрость.

Подавляющее большинство локалей не определяют свой собственный порядок сортировки, а скорее копируют порядок сортировки, определенный в /usr/share/i18n/locales/iso14651_t1_common, так что это то, что вы захотите отредактировать. Вместо того, чтобы менять порядок сортировки почти для каждой локали, модифицируя оригинал iso14651_t1_common, я предлагаю вам сделать копию. Подробности о том, как работает порядок сортировки и как создать пользовательскую локаль в вашем каталоге $HOMEбез root-доступа, можно найти в этом ответе на аналогичный вопрос .

Посмотрите, как aи Aупорядочены на основе их записей вiso14651_t1_common:

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A

bи Bаналогичны:

<U0062> <b>;<BAS>;<MIN>;IGNORE # 233 b
<U0042> <b>;<BAS>;<CAP>;IGNORE # 550 B

Мы видим, что при первом проходе aи Aимеют совпадающий символ <a>, а bи Bимеют совпадающий символ <b>. Поскольку <a>появляется перед <b>в iso14651_t1_common, aи Aсвязаны перед bи B. Второй проход не нарушает совпадения, потому что все четыре символа имеют символ сортировки <BAS>, но во время третьего прохода ничьи разрешаются, потому что символ сопоставления для строчных букв <MIN>появляется в строке 3467 перед символом сопоставления для прописные буквы<CAP>(строка 3488 ). Таким образом, порядок сортировки заканчивается как a, A, b, B.

Если поменять местами первый и третий символы сортировки, буквы будут отсортированы сначала по регистру (ниже, затем по верхнему ), затем по диакритическому знаку(<BAS>означает, что -без диакритического знака ), затем по алфавиту. Однако , как <MIN>, так и <CAP>стоят перед числовыми цифрами, так что это может привести к нежелательному эффекту размещения цифр после букв.

Самый простой способ оставить цифры первыми при установке всех строчных букв перед всеми прописными буквами — заставить все буквы совпадать во время первого сравнения, установив для них равные <a>. Чтобы убедиться, что они сортируются по регистру в алфавитном порядке, измените последний символ сортировки с IGNOREна текущий первый символ сортировки. Следуя этому шаблону, aстанет:

<U0061> <a>;<BAS>;<MIN>;<a> # 198 a

Aстанет:

<U0041> <a>;<BAS>;<CAP>;<a> # 517 A

bстанет:

<U0062> <a>;<BAS>;<MIN>;<b> # 233 b

Bстанет:

<U0042> <a>;<BAS>;<CAP>;<b> # 550 B

и так далее для остальных букв.

После того, как вы создали настроенную версию iso14651_t1_common, следуйте инструкциям в ответе, указанном выше , чтобы скомпилировать свою пользовательскую локаль.

16
27.01.2020, 19:48

Я не эксперт, но я никогда не видел локаль, которая определяет сопоставление как это. AFAIK, которым это сопоставление находится только в C, где это основано на значениях ASCII. (Обычно я просто решил бы это сценарием.)

Однако я никогда не делал этого, но Вы могли бы хотеть посмотреть на localedef (1) и локаль (5) страницы справочника для получения понимания того, как локали определяются и в конечном счете определяют собственную.

Также не забывайте, что, если существуют какие-либо диакритические знаки или специальные символы, C локаль, не будет рассматривать их, как Вы могли бы хотеть. Например, это не поместит á рядом a или Ł рядом L. В таких случаях собственная локаль языка была бы, вероятно, лучшей начальной точкой.

2
27.01.2020, 19:48
LC_COLLATE="en_US.UTF-8" sort file
-1
27.01.2020, 19:48
  • 1
    Это не сортирует нижний регистр перед верхним регистром? ideone.com/Gtyg4Z –  iiSeymour 10.05.2013, 19:06
  • 2
    Хм, в моем случае, это сделало использование Вашего примера. –  unxnut 10.05.2013, 19:59
  • 3
    @unxnut Это неправильно. Без точки с запятой команда установила бы среду для sort, но с точкой с запятой переменная локальна для оболочки и не влияет на поведение sort. Точка с запятой могла быть сохранена, как то, если бы переменная также экспортируется, но это влияло бы на другие команды также. различие –  Anders Sjöqvist 06.01.2017, 19:19

Настройка LC_COLLATE = C не всегда достаточна для сортировки прописных букв перед строчными. Возможно, вам потребуется установить LC_ALL = C .

Это также будет учитывать не буквенно-цифровые и даже непечатаемые символы, но если вы не хотите, чтобы были варианты -d и -i (описанные в man sort ), чтобы отключить это.

Скорее всего, это приведет к серьезному сбою при вводе многобайтовых символов, таких как UTF-8 с символами, отличными от ASCII.

Чтобы получить строчные буквы (по порядку) перед прописными (по порядку), лучший способ, который я могу придумать, не требующий выхода из полноценного языка программирования, - это инвертировать регистр всех букв перед сортировкой, и инвертируя их потом.

tr 'a-zA-Z' 'A-Za-z' < file | LC_ALL=C sort | tr 'a-zA-Z' 'A-Za-z'
6
27.01.2020, 19:48

Я считаю, что ответ без необходимости изменения LC_COLLATE (что означает сохранение поведения функции по умолчанию):

sort -f файл

Это работает в Linux; пожалуйста, обратитесь к разделу справки для команды, если вы используете Unix и другую версию. -f определяется как игнорирование регистра.

Спасибо за довольно (& странно) быстрое исправление и правку неуместной грамматики, Стивен Раух.

1
27.01.2020, 19:48

Теги

Похожие вопросы