如何创建文件名格式如下的变量:
文件名模式:SnapshotIR__somenumber.csv
我尝试过类似的东西:
TODAY=$(date +"%m%d%Y")
SNAPSHOT = $(SnapshotIR$TODAY*.csv)
我收到如下错误:
test.sh: line 2: SnapshotIR02122013_2239.csv: command not found
test.sh: line 2: SNAPSHOT: command not found
所以,当我想与 if 一起使用时
if [ -f SnapshotIR$TODAY*.csv] -> works
if [ -f ${SNAPSHOT} ] -> does not work (I get the above error)
答案1
SNAPSHOT = $(SnapshotIR$TODAY*.csv)
作业中不能有空格。此外,$(…)
是一个命令替换:此行尝试SnapshotIR02122013_2239.csv
作为程序执行。
在 bash、ksh 或 zsh 中,设置SNAPSHOT
为包含匹配文件名列表的数组。
SNAPSHOT=("SnapshotIR$TODAY"*.csv)
如果没有匹配的文件,则该模式不会展开。在 bash 或 zsh 中,设置nullglob
选项以获取空数组。在 ksh 中,放在~(N)
模式的开头(即SNAPSHOT=(~(N)"SnapshotIR$TODAY"*.csv)
)。然后,您可以通过测试数组的长度来测试是否有任何匹配的文件。
shopt -s nullglob
SNAPSHOT=("SnapshotIR$TODAY"*.csv)
if [ ${#SNAPSHOT} -eq 0 ]; then
echo 1>&2 "No snapshot file for $TODAY"
exit 2
elif [ ${#SNAPSHOT} -gt 1 ]; then
echo 1>&2 "Multiple snapshot files for $TODAY, I don't know which one to pick"
exit 2
fi
echo "The snapshot file is ${SNAPSHOT[0]}"
在没有数组的 shell 中,您可以使用接收匹配列表并对其进行计数的函数。如果没有匹配,该函数将接收未扩展的模式。
set_snapshot () {
if [ $# -gt 1 ]; then
echo 1>&2 "Multiple snapshot files for $TODAY, I don't know which one to pick"
exit 2
elif [ -e "$1" ]; then
SNAPSHOT=$1
else
echo 1>&2 "No snapshot file for $TODAY"
exit 2
fi
}
set_snapshot "SnapshotIR$TODAY"*.csv
echo "The snapshot file is $SNAPSHOT"
(请注意,在病态情况下,例如当没有名称为单个数字的文件但存在名称为 5 个字符的文件时,使用 来[ -e "$1" ]
测试模式是否未展开会失败。仅使用或元字符不会发生这种情况因为他们很匹配。)[0-9]
[0-9]
*
?
以下方法在一定程度上有效:
SNAPSHOT=SnapshotIR$TODAY"*.csv
if [ -e $SNAPSHOT ]; then …
由于扩展$SNAPSHOT
未加引号,因此它被视为以空格分隔的通配符模式列表,这在这里是可以的。但是,如果有多个匹配文件,则命令将把这些匹配视为单独的参数[
,这将导致语法错误。 (使用特制的文件名,甚至可能会导致错误的结果。)所以我不推荐这种方法,它太脆弱了。
答案2
当你使用$()
shell时,会将大括号内的内容作为命令执行。
不允许在=
符号之前/之后使用空格。
所以你的命令将是
SNAPSHOT=SnapshotIR$TODAY*.csv
或者
SNAPSHOT=SnapshotIR${TODAY}*.csv
附注如果您需要在下一步中对该文件进行一些操作,最好使用for
类似的循环
for file in SnapshotIR${TODAY}*.csv ; do smth ; done
因为如果您有多个文件与您的模式匹配,[ -f ${SNAPSHOT} ]
构造将返回如下错误:
[ -f f* ] && echo ok
-bash: [: filename: binary operator expected