разделитель сортировки: фигурные и квадратные скобки

Как вы сказали, выборочное тестирование небольшого файла, похоже, дает то, что вы хотите, но если вы хотите быть в безопасности, лучшим вариантом будет запись во временный файл, а затем замена нового файла в:

#!/bin/bash
scratch=$(mktemp)
trap 'rm -f "$scratch"' EXIT
if [[ -r "$1" ]]; then
    shuf "$1" --output "$scratch" && mv "$scratch" "$1"
fi

Приведенный выше сценарий можно сохранить как e. грамм. shuf_in_place в вашем ПУТИ .

2
09.09.2017, 10:28
2 ответа

Использование -k1заставит sortиспользовать всю строку в качестве ключа сортировки. Это не то, что вы хотите.

Я предполагаю, что вы хотели бы использовать exи ex2(, найденные в {...}), в качестве ключа. Для этого укажите -k2в качестве поля сортировки.

Это подберет все после первого {и использует это как ключ.

\newacronym{ex}{EX}{Expanded}
^^^^^^^^^^^ ^^^ ^^^ ^^^^^^^^^
field 1     f2  f3  field 4

\newacronym[a string]{ex2}{EX2}
^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^
field 1               f2   f3

Для только используйте второе поле в качестве ключа (, а не остальную часть строки ), используйте -k2,2.

Тестирование:

$ sort -t '{' -k2,2 file
\newacronym[a string]{ex2}{EX2}
\newacronym{ex}{EX}{Expanded}

Строка по-прежнему выходит в неправильном порядке. Это связано с тем, что ex2}сортируется до того, какex}(}идет после 2в таблице ASCII, а я использую локаль POSIX ).

Повторная попытка, но на этот раз в Ubuntu с локалью en_US.UTF-8(должна работать на любой glibc Linux и в большинстве локалей, кроме локалей Cили POSIX):

$ LC_COLLATE="en_US.UTF-8" sort -t '{' -k2,2 file
\newacronym{ex}{EX}{Expanded}
\newacronym[a string]{ex2}{EX2}

В зависимости от региональных настроек вам может потребоваться добавить бит LC_COLLATE=...или нет.


Обратите внимание, что sort— это отдельная от оболочки bashутилита, которая работает одинаково независимо от оболочки. Таким образом, это не вопрос типа «bash», а просто вопрос sort.

1
27.01.2020, 22:09

Если по какой-то причине вам нужно отсортировать по только содержимое первой пары фигурных скобок, самый простой способ, вероятно, — это декорировать -сортировать -недекорировать шаблон . Я собираюсь использоватьsedи cut, но есть много вариантов, чтобы это работало в оболочке:

sed -e 's/^\([^{]*{\([^}]*\)}\)/\2 \1/' < data|sort|cut -d' ' -f2-

Команда sedзаменяет все до конца первой пары фигурных скобок содержимым фигурных скобок, пробелом, а затем исходной строкой. Это можно отсортировать как обычно. Затем я снова cutпроверяю поле, которое добавил в начале.

Это довольно хорошо обработает нечетные символы в ключе и неравномерную длину, хотя пробелы будут проблемой, как и экранированные \}. При необходимости можно использовать другой сепаратор.


Если данные:

\newacronym{A}{EX}{Expanded}
\newacronym{F}{EX}{Expanded}
\newacronym{D}{EX}{Expanded}
\newacronym{C}{EX}{Expanded}
\newacronym[abc]{B}{EX}{Expanded}
\newacronym{CD}{EX}{Expanded}
\newacronym[def]{E}{EX}{Expanded}

, то команда sedприводит к:

A \newacronym{A}{EX}{Expanded}
F \newacronym{F}{EX}{Expanded}
D \newacronym{D}{EX}{Expanded}
C \newacronym{C}{EX}{Expanded}
B \newacronym[abc]{B}{EX}{Expanded}
CD \newacronym{CD}{EX}{Expanded}
E \newacronym[def]{E}{EX}{Expanded}

а остальное просто.

1
27.01.2020, 22:09

Теги

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