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 次 |
| 最近记录: |