bash 从文件夹中获取给定扩展名的第一个文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23423764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get first file of given extension from a folder
提问by linkyndy
I need to get the first file in a folder which has the .tar.gz
extension. I came up with:
我需要获取具有.tar.gz
扩展名的文件夹中的第一个文件。我想出了:
FILE=/path/to/folder/$(ls /path/to/folder | grep ".tar.gz$" | head -1)
but I feel it can be done simpler and more elegant. Is there a better solution?
但我觉得它可以做得更简单,更优雅。有更好的解决方案吗?
回答by devnull
You could get all the files in an array, and then get the desired one:
您可以获取数组中的所有文件,然后获取所需的文件:
files=( /path/to/folder/*.tar.gz )
Getting the first file:
获取第一个文件:
echo "${files[0]}"
Getting the last file:
获取最后一个文件:
echo "${files[${#files[@]}-1]}"
You might want to set the shell option nullglob
to handle cases when there are no matching files:
您可能希望设置 shell 选项nullglob
来处理没有匹配文件的情况:
shopt -s nullglob
回答by BMW
here is the shorter version from your own idea.
这是您自己想法的较短版本。
FILE=$(ls /path/to/folder/*.tar.gz| head -1)
回答by dogbane
You can use set
as shown below. The shell will expand the wildcard and set
will assign the files as positional parameters which can be accessed using $1
, $2
etc.
您可以使用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 ""
It is not good practice to parse ls
as you are doing, because it will not handle filenames containing newline characters. Also, the grep
is unnecessary because you could simply do ls /path/to/folder/*.tar.gz | head -1
.
像您一样进行解析ls
并不是一个好习惯,因为它不会处理包含换行符的文件名。此外,grep
是不必要的,因为您可以简单地执行ls /path/to/folder/*.tar.gz | head -1
.
回答by whoan
Here's a way to accomplish it:
这是实现它的方法:
for FILE in *.tar.gz; do break; done
You tell bash
to break
the loop in the first iteration, just when the first filename is assigned to FILE
.
你告诉bash
到break
在第一次迭代循环,就在第一个文件名被分配到FILE
。
Another way to do the same:
另一种方法来做同样的事情:
first() { FILE=; } && first *.tar.gz
Here you are using the positional parameters of the function first
which is better than set
the positional parameters of your entire bash process (as with set --
).
在这里,您使用的是函数的位置参数,first
它比set
整个 bash 进程的位置参数更好(与set --
)。
回答by Jaymon
Here's a find
based solution:
这是一个find
基于解决方案:
$ find . -maxdepth 1 -type f -iname "*.tar.gz" | head -1
where:
在哪里:
.
is the current directory-maxdepth 1
means only check the current directory-type f
means only look at files-iname "*.tar.gz"
means do a case-insensitive search for any file with the.tar.gz
extension| head -1
takes the results of find and only returns the first line
.
是当前目录-maxdepth 1
表示只检查当前目录-type f
意味着只看文件-iname "*.tar.gz"
意味着对具有.tar.gz
扩展名的任何文件进行不区分大小写的搜索| head -1
获取 find 的结果,只返回第一行
You could get rid of the | head -1
by doing something like:
您可以| head -1
通过执行以下操作来摆脱:
$ find . -maxdepth 1 -type f -iname "*.tar.gz" -maxdepth 1 -print -quit
But I'm actually not sure how portable -print -quit
is across environments (it works on MacOS and Ubuntu though).
但我实际上不确定-print -quit
跨环境的可移植性如何(尽管它适用于 MacOS 和 Ubuntu)。