我试图制作一个小脚本来转换音乐库中的某些文件。
但如果我这样做:
#!/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
,但是如果文件名/路径已经包含下划线(或者我可能使用的其他字符)下划线)?
有什么想法吗?
答案 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
我希望这可以帮助别人!