我正在尝试根据我与 case 语句一起使用的文件夹来循环具有不同搜索条件的文件。基本上是:
#!/bin/bash
case folder in
"Testordner")
search_filename=*_0_*.txt
;;
"Ordner2")
search_filename=*_65_*fg*.txt
;;
*)
;;
esac
for files in $search_filename; do
echo $files
done
我原本希望在最后的回声中获得符合搜索标准的文件列表。相反,我得到了搜索标准本身。
为了测试,我F="*.txt";for files in $F;do echo $files;done
直接在 bash 中尝试(它有效,我得到了文件列表)和同一个脚本(这让我得到了输出)*.txt
已经尝试了不同的变量扩展内容(例如$(..) ((..)) ${..}
,所有这些都不起作用。)
这是为什么?我该如何解决?
找到帮助会很高兴。最美好的祝愿卡罗
使用 Ubuntu 22.04LTS、KDE/plasma 桌面; bash v5.1.16(1)。终端:konsole v21.12.3
答案1
在 Bash 中,如果nullglob
禁用(通常是默认值),在没有匹配的情况下,全局模式将计算/扩展为自身(例如,*.txt
计算为文字 string *.txt
)。启用后nullglob
(通常更适合脚本),在没有匹配的情况下,全局模式将计算/扩展为空字符串。
如果您的脚本从不同的目录运行,您的 glob 将以不同的方式扩展(当然,除非每个目录中都存在相同的文件名)。
例如:
user@host:~ 0 $ touch {a,b,c}.log
user@host:~ 0 $ ls -l
total 0
-rw------- 1 user staff 0 Jul 25 10:27 a.log
-rw------- 1 user staff 0 Jul 25 10:27 b.log
-rw------- 1 user staff 0 Jul 25 10:27 c.log
user@host:~ 0 $ shopt nullglob
nullglob off
user@host:~ 1 $ echo *.log
a.log b.log c.log
user@host:~ 0 $ echo *.bak
*.bak
user@host:~ 0 $ shopt -s nullglob
user@host:~ 0 $ shopt nullglob
nullglob on
user@host:~ 0 $ echo *.log
a.log b.log c.log
user@host:~ 0 $ echo *.bak
user@host:~ 0 $
在一个不相关的注释上……也许可以考虑将故意引用习惯化,至少在适当的时候;例如,echo "$files"
,而不是echo $files
提高命令行安全性和空白处理。
如果有兴趣,也可能需要使用数组;例如,
#!/bin/bash -e
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
shopt -s nullglob
declare -a files=()
case "$1" in
'logs')
files=(*.log)
;;
'baks')
files=(*.bak)
;;
*)
echo 'invalid argument' 1>&2
exit 1
;;
esac
for f in "${files[@]}"; do
echo "$f"
done