Bash 从文件夹中获取给定扩展名的第一个文件

Bash 从文件夹中获取给定扩展名的第一个文件,bash,Bash,我需要获取扩展名为.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[${#f

我需要获取扩展名为
.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]}"
您可能需要设置shell选项
nullglob
,以处理没有匹配文件的情况:

shopt -s nullglob

这是你自己想法的简短版本

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

您可以使用
set
,如下所示。shell将展开通配符,
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"

这不是一个很好的实践,因为它不会处理包含换行符的文件名。另外,
grep
是不必要的,因为您可以简单地执行
ls/path/to/folder/*.tar.gz | head-1

以下是一种实现方法:

for FILE in *.tar.gz; do break; done
当第一个文件名被分配给
文件时,您告诉
bash
在第一次迭代中中断循环


另一种方法是:

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

在这里,您首先使用函数
的位置参数
,这比
设置
整个bash过程的位置参数(与
设置--
一样)要好。

下面是一个基于
查找
的解决方案:

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

  • 是当前目录
  • -maxdepth 1
    表示只检查当前目录
  • -类型f
    表示只查看文件
  • -iname“*.tar.gz”
    表示对扩展名为
    .tar.gz
    的任何文件进行不区分大小写的搜索
  • | head-1
    获取find的结果并仅返回第一行
您可以通过执行以下操作来摆脱
|head-1

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

但我实际上不确定
-print-quit
在不同环境中的可移植性(它在MacOS和Ubuntu上都能工作)。

如何定义“第一”?字母排序,大小排序?理论上是按字母升序排列的第一个,实际上会有一个扩展名的文件…这似乎有点过分,我的变体虽然有一些冗余代码,但行数较少…@AndreiHorak不太理解这个问题。如果您知道路径和文件扩展名,有许多方法比解析
ls
更好。例如,
echo/path/*.tar.gz | cut-d''-f1
假设文件名没有空格。2备注:1。要回显数组
files
的最后一个元素,命令
echo“${files[-1]}”
也将起作用。2.如果没有文件(并且设置了
nullglob
),则会得到错误的数组下标。在这种情况下,您可能需要用<代码>((${x文件[@)})和&回声“${Frase[-1”}“< /代码> .@ DEVNUL-这是问题,我知道我的方法不是最好的:”您的示例看起来更好,我会考虑它。