在Bash中查找文件名并将其赋值给变量

3
我想在服务器的文件夹中找到一个文件的名称,并将其设置为变量以便以后使用。问题是,当我运行备份脚本时,文件名会因日期而更改。因此,我不能只是硬编码文件名和路径。
例如,我知道文件的位置 - /var/backups/"unknownfilename.sql"
 backuppath="/var/backups/"

我该如何将$backuppath中的文件设置为$backupfile?

经过研究,我只发现人们会将文件名echo出来,但他们从未将其存储到变量中。


你可以使用 var=$(command) 将任何命令的输出分配给变量。 - Barmar
...但是如果有一个目录里只有一个文件(正如问题所暗示的那样),使用find命令就有些愚蠢了。 - Charles Duffy
抱歉,你是对的,我的错误。 - Drew
空格也是错误的。backuppath = "/var/backups/" 尝试运行一个名为 backuppath 的命令,其第一个命令行参数为 =,第二个命令行参数为 /var/backups/ - Charles Duffy
1个回答

9

对于bash (#!/bin/bash):

backuppath=/var/backups
sqlfiles=( "$backuppath"/*.sql )
[[ -e $sqlfiles ]] || { echo "Matched no files" >&2; exit 1; }

如果您想引用第一个匹配项:

echo "The first match found was: $sqlfiles"

如果您想引用所有数组内容:
echo "Found the following files:"
printf '- %q\n' "${sqlfiles[@]}"

对于POSIX sh脚本(#!/bin/sh),请使用以下方式:
backuppath=/var/backups

# wrap in a function to avoid overwriting the global $1, $2, etc.
find_files() {
  set -- "$backuppath"/*.sql
  [ -e "$1" ] || { echo "Matched no files" >&2; exit 1; }
  [ "$#" -gt 1 ] && echo "WARNING: Matched $# files; only taking first" >&2
  sqlfile=$1
}
find_files

注意事项:

  • 备份路径("$backuppath")本身应该在引号内;通配符表达式(*.sql)则不需要。
  • 检测第一个找到的元素是否存在([[ -e $sqlfiles ]]在Bash中,[ -e "$1" ]则在POSIX sh版本中)可以防止默认行为,即当没有匹配时,将使用通配符表达式本身(/var/backups/*.sql)作为结果;如果进行存在性测试,则除非存在名字中包含一个星号的文件(也就是说,一个名字包含一个星号),否则该表达式不会被包括在内。
  • 第一种形式使用了Bash中存在的两种行为:数组和扩展的([[ ]])测试运算符。如果你要使用标准的测试命令,那么它将是[ -e "$sqlfiles" ];如果你要在没有数组的shell中操作,你可以将这个逻辑包装在一个函数中,并使用set -- "$backuppath"/*.sql将结果放入类似数组的对象"$@"中,此后可以将第一个匹配项称为"$1",或者将整个匹配集合称为"$@"

谢谢,这就是我要找的内容。 sqlfiles=(“$backuppath” / * .sql) - Drew
实际上,如果有多个文件,你怎么才能让它找到文件夹中的最后一个文件呢? - Drew
按名称排序的“last”,或按日期排序的“latest”?前者将是 "${sqlfiles[${#sqlfiles[@]} - 1]}";后者是BashFAQ#3的主题:http://mywiki.wooledge.org/BashFAQ/003。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接