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

问题描述 投票:0回答:2

我可以在ubuntu bash和windowscygwin bash上重现这个问题,这个问题发生在文件和目录名有空格的情况下,这是我的脚本,叫做pass-dir-name-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实现一个过滤器来删除文件名。

用backtickperl的方法是行不通的! 这是我第一次尝试转义空格。

./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忽略了我的引号! 似乎是"$@"出了问题! 我怎样才能过滤掉文件名?

谢谢你

齐格弗里德

bash perl
2个回答
2
投票

这是你传递目录名的方式不对。

你需要像这样重新组织调用(简化版的perl脚本)。

readarray -t -d '' dirs < <(perl -e 'print "$_\x00"')
./pass-dir-names-with-spaces.sh "${dirs[@]}"

1
投票
  • 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\0' |
  xargs -0 ./pass-dir-names-with-spaces.sh
© www.soinside.com 2019 - 2024. All rights reserved.