Мне нужно получить первый файл в папке с расширением .tar.gz
. Я придумал:
FILE=/path/to/folder/$(ls /path/to/folder | grep ".tar.gz$" | head -1)
но я чувствую, что это можно сделать проще и элегантнее. Есть ли лучшее решение?
Мне нужно получить первый файл в папке с расширением .tar.gz
. Я придумал:
FILE=/path/to/folder/$(ls /path/to/folder | grep ".tar.gz$" | head -1)
но я чувствую, что это можно сделать проще и элегантнее. Есть ли лучшее решение?
Вы можете получить все файлы в массиве, а затем получить желаемый результат:
files=( /path/to/folder/*.tar.gz )
Получение первого файла:
echo "${files[0]}"
Получение последнего файла:
echo "${files[${#files[@]}-1]}"
Возможно, вы захотите установить опцию оболочки nullglob
для обработки случаев, когда нет соответствующих файлов:
shopt -s nullglob
вот более короткая версия из вашей собственной идеи.
FILE=$(ls /path/to/folder/*.tar.gz| head -1)
Вы можете использовать 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
.
Вот способ сделать это:
for FILE in *.tar.gz; do break; done
Вы указываете bash
на break
цикл в первой итерации, только когда первое имя файла назначается FILE
.
Другой способ сделать то же самое:
first() { FILE=$1; } && first *.tar.gz
Здесь вы используете позиционные параметры функции first
, которая лучше, чем set
позиционные параметры всего вашего процесса bash (как с set --
).
Вот решение на основе 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).