我想运行此cmd行脚本
$ script.sh lib/* ../test_git_thing
我希望它能处理/ lib文件夹中的所有文件。
FILES=$1
for f in $FILES
do
echo "Processing $f file..."
done
目前它只打印第一个文件。如果我使用$ @,它会给我所有文件,但也是我不想要的最后一个参数。有什么想法吗?
答案 0 :(得分:2)
正如所指出的那样,命令行上的lib/*
正在扩展为lib
中的所有文件。为防止扩展,您有2个选项。 (1)引用你的意见:
$ script.sh 'lib/*' ../test_git_thing
或(2),关闭文件全局。但是,选项set -f
将禁用shell中的路径名扩展,但它将禁用所有路径名扩展(在将参数传递给脚本之前,在shell中进行扩展时,在脚本中设置它并不会有帮助) 。在您的情况下,最好引用输入或将第一个参数作为目录名传递,并在脚本中添加扩展:
DIR=$1
for f in "$DIR"/*
答案 1 :(得分:1)
当您调用“script.sh lib / *”时,在命令行中展开参数列表,并使用lib / as args中的所有文件调用您的脚本。由于您只在脚本中引用$ 1,因此它只打印第一个文件。您需要在命令行中转义通配符,以便将其传递给您的脚本以执行通配。
答案 2 :(得分:1)
在bash和ksh中,你可以遍历除了最后一个之外的所有参数:
for f in "${@:1:$#-1}"; do
echo "$f"
done
在zsh中,你可以做类似的事情:
for f in $@[1,${#}-1]; do
echo "$f"
done
$#
是参数的数量,${@:start:length}
是bash和ksh中的子字符串/子序列表示法,而$@[start,end]
是zsh中的子序列。在所有情况下,下标表达式都被计算为算术表达式,这就是$#-1
工作的原因。 (在zsh中,您需要${#}-1
,因为$#-
被解释为" $-
"的长度。)
在所有三个shell中,您可以使用带有标量变量的${x:start:length}
语法来提取子字符串;在bash和ksh中,您可以将${a[@]:start:length}
与数组一起使用来提取值的子序列。
答案 3 :(得分:0)
这回答了给定的问题,没有使用非POSIX功能,也没有解决方法,例如禁用globbing。
您可以使用循环找到最后一个参数,然后在处理文件列表时将其排除。在此示例中,$d
是目录名称,而$f
与原始答案中的含义相同:
#!/bin/sh
if [ $# != 0 ]
then
for d in "$@"; do :; done
if [ -d "$d" ]
then
for f in "$@"
do
if [ "x$f" != "x$d" ]
then
echo "Processing $f file..."
fi
done
fi
fi
此外,最好还测试"$f"
是否是一个文件,因为如果找不到匹配项,shell通常会通过参数列表传递通配符。