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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:22:13  来源:igfitidea点击:

Get first file of given extension from a folder

bash

提问by linkyndy

I need to get the first file in a folder which has the .tar.gzextension. 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 nullglobto 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 setas shown below. The shell will expand the wildcard and setwill assign the files as positional parameters which can be accessed using $1, $2etc.

您可以使用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 lsas you are doing, because it will not handle filenames containing newline characters. Also, the grepis 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 bashto breakthe loop in the first iteration, just when the first filename is assigned to FILE.

你告诉bashbreak在第一次迭代循环,就在第一个文件名被分配到FILE



Another way to do the same:

另一种方法来做同样的事情:

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

Here you are using the positional parameters of the function firstwhich is better than setthe positional parameters of your entire bash process (as with set --).

在这里,您使用的是函数的位置参数,first它比set整个 bash 进程的位置参数更好(与set --)。

回答by Jaymon

Here's a findbased solution:

这是一个find基于解决方案:

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

where:

在哪里:

  • .is the current directory
  • -maxdepth 1means only check the current directory
  • -type fmeans only look at files
  • -iname "*.tar.gz"means do a case-insensitive search for any file with the .tar.gzextension
  • | head -1takes 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 -1by 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 -quitis across environments (it works on MacOS and Ubuntu though).

但我实际上不确定-print -quit跨环境的可移植性如何(尽管它适用于 MacOS 和 Ubuntu)。