Чи можу я вибрати один результат із глобуса bash?


14

Я намагаюся написати сценарій для роботи, щоб автоматизувати деяку звітність про вихід. Файли журналу (зараз це "стандартизувати" в майбутньому) зберігаються в такій структурі шляху:

/<root_path>/<process_one_path>/logs/<time_date_stamp>/<specific_log_file>

/<root_path>/<process_two_path>/logs/<different_time_date_stamp>/<specific_log_file>

Кожна частина шляху відома, за винятком штампів дати, які завжди є останніми в папці.

Якщо я спробую використати підстановку замість штампа дати, я отримаю кілька результатів, наприклад:

> ls /<root_path>/<process_two_path>/logs/* [tab]
20130102-175103
20130118-090859
20130305-213506

Я хочу лише, щоб він повернув останній, чи можливо це з Bash?

NB (у мене немає zsh, і настільки мило, як це звучить, я сумніваюся, що коли-небудь це отримаємо на роботі)

Відповіді:


9

Наступні роботи з bash 4.2:

list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[-1]}"

Якщо ваш баш - це стара версія:

list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[${#list[@]}-1]}"

Це безумовно працює на моєму домашньому комп’ютері, але я не можу гарантувати, що він буде працювати на роботі?
Pureferret

@Pureferret частина, яка може не працювати, - це індекс негативного масиву ( -1). Це було додано в базі 4.2. RHEL5 - це, мабуть, найстаріший підтримуваний базовий дистрибутив підприємства, який використовує bash 4.2.20.
Патрік

1
Старіші версії bashhave: "${list[@]: -1}"like in ksh93( [-1]походить від zsh).
Стефан Шазелас

@Patrick - RHEL5 використовує bash 3.2. RHEL 3 і 4 все ще підтримуються протягом тривалого життя.
Йорданм

1
@Pureferret Ви також можете робити арифметику з довжиною масиву, дивіться мою редагування.
Жил "ТАК - перестань бути злим"

10

POSIXly:

 set -- /<root_path>/<process_two_path>/logs/*
 shift "$(($# - 1))"
 printf '%s\n' "$1"

Оскільки ви згадуєте zsh:

 print -r /<root_path>/<process_two_path>/logs/*([-1])

4

Використовуйте глобус bash в башті для циклу. Подобається це:

for filename in <logdir>/*; do :; done; echo "$filename"

Це залежить від того, що bash робить глобальне розширення відсортованим за алфавітом. Прочитайте посібник з bash для отримання додаткової інформації. Зауважте, що це залежить від LC_COLLATE . Це також залежить від того, що змінна filenameвсе ще містить останнє значення після припинення циклу.

Якщо ви хочете, щоб ім'я файлу з найстарішою часовою позначкою ви можете зробити так:

for filename in <logdir>/*; do echo "$filename"; break; done

1

-1 - це за замовчуванням у трубопроводах, а вихід ls вже повинен бути відсортований:

ls | tail -n1

Якщо інші шукали, як інтерактивно вставити перший чи останній результат, ви можете прив’язати меню. Повне або меню-повне-назад у .inputrc:

"\e\t": menu-complete
"\e[Z": menu-complete-backward # shift-tab

Якщо параметр show-all-if-multiiguble увімкнено, set completion-query-items 0видаляє підказку, коли є 101 або більше результатів, і set page-completions offвимикає пейджер.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.