Shell脚本变量结构

Shell脚本变量结构

如何创建文件名格式如下的变量:

文件名模式: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

答案3

不是=在when周围使用空格分配变量

另外,我认为您不想将SNAPSHOT分配给的内容括起来,$( )因为它试图将其作为命令执行。

附带说明一下,考虑小写你的变量

所以你想要的可能是

today=$(date +"%m%d%Y")    
snapshot=SnapshotIR$today

if [ -f ${snapshot}*.csv ]

相关内容