理解(多个和自动)文件名引用

时间:2013-04-01 22:01:54

标签: bash filenames spaces

我正在启动bash脚本,我无法处理间隔文件名。我在这里搜索了有关我的问题的其他问题,例如:

how to output file names surrounded with quotes in SINGLE line?

在我的剧本中,我需要接受所有的导演,为每个人做一些工作。所以我的脚本的骨架是:

for directory in `find "$DIR" -type d`
do
# ... some work ...
done

此脚本不适用于间隔文件名。所以我尝试将find与exec结合使用,这似乎是一个优雅而简单的解决方案,但没有任何改变。更确切地说,我试过:

(I)  find "$DIR" -type d -exec echo -n '"{}" ' \;
(II) find "$DIR" -type d -exec echo -n '"{}" ' +

在使用命令-exec之前,我读了一些关于它的内容,但我仍然不清楚,所以:

  1. 是什么以及如何运作'“{}”'\;
  2. “{}”'+
  3. 是什么以及如何运作
  4. 我如何修复我的脚本也用于间隔文件名?

3 个答案:

答案 0 :(得分:2)

  

是什么以及如何运作'“{}”'\;

对于每个文件名,这基本上会执行echo -n "\"filename\" ",产生一堆像"filename"这样的行。

添加文字引号并没有帮助,因为bash没有开始将数据解释为shell脚本代码。

如果你read foo; ls $foo,你不能只输入$(rm /)来运行一个命令,你不能只输入"foo bar"来避免拆分文件名。数据是数据,而不是代码,并且不遵守shell语法。

  

“{}”'+

是什么以及如何运作

+为文件名组运行一次​​命令(为了效率,而不是一次一个)。由于替换的工作方式,它与{} +相同,因为参数只是被删除并被一堆文件名替换。

  

我如何修复我的脚本也用于间隔文件名?

通过使用IFS变量,只需更改bash用于拆分的字符,就可以使其在95%的情况下工作:

IFS=$'\n'
for dir in $(find "$DIR" -type d)
do 
   echo "Directory: >> $dir <<"
done

这使得bash只分为换行符而不是所有空格的默认值(这可能会在其余代码中产生一些有趣的副作用,因此您可能希望之后将IFS的值设置回原来的值)。

文件名也可以包含换行符。最好的方法是使用:

while IFS= read -d '' -r dir
do
    echo "Directory: >> $dir <<"
done < <(find "$DIR" -type d -print0)

使find输出文件被NUL字节拆分,文件名永远不能包含。

答案 1 :(得分:1)

这可能对您更有效:

while IFS= read -r adir ; do
    echo "Directory: $adir"
done < <(find "$DIR" -type d)

答案 2 :(得分:1)

我使用这种格式&amp;它工作正常:

find '/path/to/directories' -type d |\
  while read DIRNAME
  do
    echo "${DIRNAME}"
  done