Как вы сказали, выборочное тестирование небольшого файла, похоже, дает то, что вы хотите, но если вы хотите быть в безопасности, лучшим вариантом будет запись во временный файл, а затем замена нового файла в:
#!/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
в вашем ПУТИ
.
Использование -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
.
Если по какой-то причине вам нужно отсортировать по только содержимое первой пары фигурных скобок, самый простой способ, вероятно, — это декорировать -сортировать -недекорировать шаблон . Я собираюсь использовать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}
а остальное просто.