我正在启动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之前,我读了一些关于它的内容,但我仍然不清楚,所以:
答案 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