Как отсортировать массив zsh по дате модификации?

Спасибо, что указали мне на другую связанную тему .

Для меня ключевым было использование переменной BASH _ENV.

Как отмечено в справочном руководстве по bash, существует несколько способов открыть оболочку , один из которых вызывал у меня затруднения, когда он вызывался «не -интерактивно».

Чтобы обойти тот факт, что не -интерактивная оболочка не запускает ни /etc/profile, ни /etc/bashrc, я создал специальный сценарий оболочки в /etc/profile.d/, например. «пользовательский _shopts.sh» только с параметрами shopt, которые я хотел бы иметь для каждой сессии, и в этом же скрипте я экспортирую переменнуюBASH_ENV=/etc/profile.d/custom_shopts.sh

Таким образом, в любой оболочке, которую я запускаю (оболочка входа в систему, интерактивная оболочка или не -интерактивная оболочка, но за исключением bash --posix), сценарий оболочки /etc/profile.d/custom_shopt.shзапускается и устанавливает параметры магазина. Я ожидаю.

3
07.04.2020, 22:54
3 ответа

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

set -A files $(ls -trd -- ~/a ~/b ~/c)

Здесь вывод lsразделен на $IFSсимвол (, по умолчанию содержащий SPC, TAB, LF и NUL ). Чтобы разделить только LF (, чтобы иметь возможность работать с именами файлов, которые содержат символы SPC или TAB (, но явно не LF )), вы можете установить IFS=$'\n'или использовать флаг расширения параметра f:

files=(${(f)"$(ls -trd -- $files)"})

(здесь также используется синтаксис стиля zsh -array=(...)вместо стиля ksh88 -set -A array..., поскольку этот синтаксис в любом случае уже специфичен для zsh -).

2
28.04.2021, 23:18

Будет намного проще отсортировать список при его построении . Но если не можешь…

Классический подход состоит в том, чтобы добавить критерий сортировки к данным, затем отсортировать их, а затем удалить добавленный мусор. Создайте массив, содержащий временные метки и имена файлов, таким образом, чтобы это было однозначно и с временными метками в формате, который можно отсортировать лексикографически. Отсортируйте массив (, используя флаг раскрытия параметраo), затем удалите префикс. Вы можете использовать модульstatдля получения времени модификации файла.

zmodload zsh/stat
for ((i=1; i<$#files; i++)); do times[$i]=$(stat -g -F %020s%N +mtime -L -- $files[$i]):$files[$i]; done
sorted=(${${(o)times}#*:})

Формат %Nдля zstat (для получения меток времени с наносекундным разрешением )требует zsh ≥5,6. Если ваш zsh старше, удалите его, и код все равно будет работать, но сравнивая метки времени с разрешением 1 -секунды. Многие файловые системы имеют разрешение в доли секунды, но я не думаю, что вы можете получить его с помощью модуля zsh statв более старых версиях zsh.

Если ваш zsh слишком старый, вы можете получить более точные метки времени с помощью утилиты statиз GNU coreutils . Если он у вас есть, у вас, вероятно, есть и другие основные утилиты GNU, поэтому я буду использовать их. Утилиты GNU coreutils обычно присутствуют во встроенных Linux, отличных от -, но могут отсутствовать в BSD или macOS. В macOS их можно установить с помощью brew. Если основные утилиты GNU не являются частью базовой операционной системы, вам может потребоваться изменить statна gstat, sortна gsortи cutна gcut.

if (($#files)); then
  sorted=(${(0@)"$(stat  --printf='%040.18Y:%n\0' "$files[@]" | sort -rz | cut -z -d':' -f2-)"})
else
  sorted=()
fi

Альтернативный подход zsh заключается в создании шаблона, включающего все файлы из $filesи другие. Отсортируйте файлы, соответствующие этому шаблону, а затем отфильтруйте их, чтобы включить только нужные файлы. Вам нужно построить весь шаблон для more_files, что не всегда практично.

more_files=(~/*(Om))
sorted=(${more_files:*files})
4
28.04.2021, 23:18

Вы можете использовать подход, аналогичный этому:

zmodload zsh/stat

array=(file1 file2...)

# store mtimes in an associative array:
typeset -A mtime
stat -nLF %s.%N -A mtime +mtime -- $array

# sort using the Oe glob qualifier
sorted_array=(/(e['reply=($array)']nOe['REPLY=$mtime[$REPLY]'])

(%Nдля наносекунд требуется zsh 5.6 или новее ).

3
28.04.2021, 23:18

Теги

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