sup*_*ted 6 linux bash shell ubuntu bash-scripting
我试图在/foo
保留列出目录中的空格的同时回显所有文件。目前,名为目录"bar1 bar2"
将回声出作为/path/to/foo/bar1/
然后/bar2
再file.txt
全部上新的生产线。我需要它来 echo/path/to/foo/bar1 bar2/file.txt
或/path/to/foo/bar1\ bar2/file.txt
.
for file in $(find /path/to/foo/ -type f); do
if [[ ... ]]; then
echo "${file}"
fi
done
Run Code Online (Sandbox Code Playgroud)
还试过:
for file in $(find /path/to/foo/ -type f | sed 's/ /\ /g'); do
if [[ ... ]]; then
echo "${file}"
echo "$file" # variations i've tried
echo $file # variations i've tried
echo ${file}
otherCommand "${file}"
fi
done
Run Code Online (Sandbox Code Playgroud)
use*_*686 16
问题不在于 ,而在于$file
您对$(find…)
.
常规变量和$(…)
过程替换都受到完全相同的分词。如果你把$(find…)
在双引号,你会得到一个单一的与所有输出字。-如果你不这样做,它会在任何空白被分割不只是换行或其他一些神奇的边界,你可能期望。
上面的一个重要部分是在扩展变量时不处理反斜杠转义。它只是在空格处分开,仅此而已。
(换句话说,引用$file
没有帮助,因为它从来没有正确的值!)
如果要递归处理所有文件,您的选择是:
find
以另一种方式读取输出:
find … -print | while read -r file; do
echo "Got $file"
done
Run Code Online (Sandbox Code Playgroud)
(旁注:文件名在技术上也可能包含换行符,因此您可能需要防范这种情况,尽管这种情况很少见:
find … -print0 | while read -r -d "" file; do
echo "Got $file"
done
Run Code Online (Sandbox Code Playgroud)对于少量文件,使用 bash 的扩展通配符:
shopt -s globstar
for file in /path/to/foo/**; do
echo "Got $file"
done
Run Code Online (Sandbox Code Playgroud)对于大型目录,优点find | while read
是它是流式传输的——您的脚本将在结果出现时对其进行处理。同时,$(find)
通配符和通配符都必须首先将所有内容收集到内存中,然后才返回(可能是大量的)结果。
另一方面,使用管道会影响整个 while
循环(不仅仅是read
命令),所以如果你想运行任何想要读取键盘输入的东西,你必须手动为它提供原始标准输入,例如vim "$file" < /dev/tty
.
归档时间: |
|
查看次数: |
2167 次 |
最近记录: |