如何避免在zsh for-loop中使用空格作为分隔符?

时间:2015-10-11 04:28:27

标签: for-loop sh zsh separator

我试图制作一个小脚本来转换音乐库中的某些文件。

但如果我这样做:

#!/usr/bin/zsh                                                                     

for x in $(find -name "*.m4a");
do
    echo $x;
done

在包含以下内容的文件夹中进行解释时

foo\ bar.m4a

它将返回:

foo
bar.m4a

如何阻止for循环将空格字符解释为分隔符?

我可以用$(find -name "*.m4a")替换$(find -name "*.m4a" | sed "s/ /_/g"),然后在循环中使用sed,但是如果文件名/路径已经包含下划线(或者我可能使用的其他字符)下划线)?

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

您可以通过双引号来阻止命令替换的单词拆分:

#!/usr/bin/zsh                                                                     

for x in "$(find -name "*.m4a")"
do
    echo "$x"
done

请注意,命令替换中的双引号不会与其外部的双引号发生冲突(我之前实际上从未注意到这一点)。如果您发现它更具可读性,就可以轻松使用单引号,如"$(find -name '*.m4a')"中所示。无论如何,我通常会使用带有find原色的单引号。

出于同样的原因,在循环体内引用是很重要的。它将确保x的值作为单个参数传递。

但这绝对是一种混合的科学怪人解决方案。您最好使用globbing或使用find,如下所示:

find . -name '*.mp3' -exec echo {} \;

但这种形式是有限的。您可以添加其他-exec原色,这些原色将像&&分隔的shell命令一样执行,但您无法从一个-exec传送到另一个#include <iostream> using namespace std; int main() { string str{ "10110011" }; // max length can be sizeof(int) X 8 int dec = 0, mask = 1; for (int i = str.length() - 1; i >= 0; i--) { if (str[i] == '1') { dec |= mask; } mask <<= 1; } cout << "Decimal number is: " << dec; // system("pause"); return 0; } ,您可以&#39 ; t与shell交互(例如通过分配或扩展参数)。

答案 1 :(得分:2)

在此处使用zsh的通讯设施,而不是find

for x in **/*.m4a; do
    echo "$x"
done

$x的默认设置下,在循环体中引用zsh是可选的,但无论如何这都是不错的主意。

答案 2 :(得分:0)

我发现了。

正如此处所示:https://askubuntu.com/questions/344407/how-to-read-complete-line-in-for-loop-with-spaces

我可以将IFS(内部字段分隔符)设置为'\ n'。

这样可行:

#!/usr/bin/zsh                                                                                          

IFS=$'\n'
for x in $(find -name "*.m4a");
do
    echo $x;
done

我希望这可以帮助别人!