Получить первый файл данного расширения из папки

Мне нужно получить первый файл в папке с расширением .tar.gz. Я придумал:

FILE=/path/to/folder/$(ls /path/to/folder | grep ".tar.gz$" | head -1)

но я чувствую, что это можно сделать проще и элегантнее. Есть ли лучшее решение?

Ответ 1

Вы можете получить все файлы в массиве, а затем получить желаемый результат:

files=( /path/to/folder/*.tar.gz )

Получение первого файла:

echo "${files[0]}"

Получение последнего файла:

echo "${files[${#files[@]}-1]}"

Возможно, вы захотите установить опцию оболочки nullglob для обработки случаев, когда нет соответствующих файлов:

shopt -s nullglob

Ответ 2

вот более короткая версия из вашей собственной идеи.

FILE=$(ls /path/to/folder/*.tar.gz| head -1)

Ответ 3

Вы можете использовать set, как показано ниже. Оболочка расширит подстановочный знак и set назначит файлы в качестве позиционных параметров, к которым можно получить доступ, используя $1, $2 и т.д.

# set nullglob so that if no matching files are found, the wildcard expands to a null string
shopt -s nullglob

set -- /path/to/folder/*.tar.gz

# print the name of the first file
echo "$1"

Не рекомендуется использовать parse ls, поскольку он не будет обрабатывать имена файлов, содержащие символы новой строки. Кроме того, grep не требуется, потому что вы можете просто сделать ls /path/to/folder/*.tar.gz | head -1.

Ответ 4

Вот способ сделать это:

for FILE in *.tar.gz; do break; done

Вы указываете bash на break цикл в первой итерации, только когда первое имя файла назначается FILE.


Другой способ сделать то же самое:

first() { FILE=$1; } && first *.tar.gz

Здесь вы используете позиционные параметры функции first, которая лучше, чем set позиционные параметры всего вашего процесса bash (как с set --).

Ответ 5

Вот решение на основе find:

$ find . -maxdepth 1 -type f -iname "*.tar.gz" | head -1

где:

  • . является текущим каталогом
  • -maxdepth 1 означает только проверку текущего каталога
  • -type f означает только просмотр файлов
  • -iname "*.tar.gz" означает поиск любого файла без учета регистра с расширением .tar.gz
  • .| head -1 принимает результаты поиска и возвращает только первую строку

Вы можете избавиться от | head -1, сделав что-то вроде:

$ find . -maxdepth 1 -type f -iname "*.tar.gz" -maxdepth 1 -print -quit

Но на самом деле я не уверен, насколько портативен -print -quit в разных средах (хотя он работает на MacOS и Ubuntu).