如何将当前路径的目录名称(带空格)作为参数传递给 bash 脚本?



我可以在ubuntu-bash和windows/cygwin-bash上重现这个问题。这个问题发生在文件名和目录名中有空格的情况下。这是我的脚本,名为pass-dir-names-with-spaces.sh:

for dir in "$@"
do
echo dir = $dir
done

这很好:

./pass-dir-names-with-spaces.sh *
dir = pass-file-names-with-spaces.sh
dir = this is a directory with spaces in it
dir = this is a file name with spaces.txt
dir = this is another file name with spaces.txt

我在每一行都得到完整的文件名,即使其中有空格。有时这是完全可以接受的,因为我想要文件名和目录名。然而,有时我想用perl实现一个过滤器来删除文件名。

backtick/perl方法不起作用!这是我第一次尝试逃离太空。

./pass-dir-names-with-spaces.sh `perl -e ' my @m  = (); my $c = shift @ARGV; opendir $h, $c or die "cannot opendir $c"; @a= map { push @m, $_ if  -d $_ } grep(!/^..$/,readdir $h); closedir $h; foreach (@m){s/ /\\ /g; print " $_ " } '  .`
dir = .
dir = this
dir = is
dir = a
dir = directory
dir = with
dir = spaces
dir = in
dir = it

我试着用引号代替:

./pass-dir-names-with-spaces.sh `perl -e ' my @m  = (); my $c = shift @ARGV; opendir $h, $c or die "cannot opendir $c"; @a= map { push @m, $_ if  -d $_ } grep(!/^..$/,readdir $h); closedir $h; foreach (@m){ print " "$_" " } '  .`
dir = "."
dir = "this
dir = is
dir = a
dir = directory
dir = with
dir = spaces
dir = in
dir = it"

看来bash忽略了我的语录!看来"$@"行为不端!如何过滤掉文件名?

感谢

齐格弗里德

传递目录名的方式不对。

您需要像这样重新构建调用(perl脚本的简化版本(:

readarray -t -d '' dirs < <(perl -e 'print "$_x00"')
./pass-dir-names-with-spaces.sh "${dirs[@]}"
  • set --:清空参数数组
  • for d in *; do:将每个目录条目作为变量d进行迭代
  • [ -d "$d" ] && set -- "$@" "$d":如果条目d是目录,则将其添加到参数数组中
  • ./pass-dir-names-with-spaces.sh "$@":最后将参数数组传递给脚本或命令
set --
for d in *; do
[ -d "$d" ] && set -- "$@" "$d"
done
./pass-dir-names-with-spaces.sh "$@"

现在,为了反映@Shellter的建议,让我们使用find:

find . -mindepth 1 -maxdepth 1 -type d -exec ./pass-dir-names-with-spaces.sh {} +

或者,如果find对于-exec command {} +语法来说太旧:

find . -mindepth 1 -maxdepth 1 -type d -printf '%f' |
xargs -0 ./pass-dir-names-with-spaces.sh

最新更新