我想在字符串中添加一个字符串到目录中的所有文件。我想做的是:
echo string{$(ls some_dir)}
这不会起作用,因为ls用空格分隔单词,而大括号扩展需要逗号。所以我想我会用tr
用空格替换空格,例如:
echo string{$(ls some_dir) | tr ' ' ','}
但这不起作用,因为管道优先。
这样做的正确方法是什么?我知道我可能会使用像Python这样理智的语言,但令人沮丧的是,Bash甚至不能做那么简单的事情。
答案 0 :(得分:3)
如果你真的想插入目录的内容(这是$(ls some_dir)会给你的)那么你可以做
printf 'string%s ' some_dir/*
IRL,您可能希望以换行结束。
{ printf 'string%s ' some_dir/*; echo; }
您可以将此概括为任何glob或大括号扩展的输出:
printf 'foo%d\n' {11..22}
根据您的评论,您想要消除" some_dir /"另一方面,你不能只用printf
做到这一点。您可以cd
到目录,以便根据需要展开globs,或使用参数扩展来清理前导目录名称:
( cd some_dir && printf 'string%s ' *; echo )
或
{ cd some_dir && printf 'string%s ' * && cd - >/dev/null; echo; }
或
names=( some_dir/* ) names=( "${names[@]#some_dir/}" )
{ printf 'string%s ' "${names[@]}"; echo; }
答案 1 :(得分:0)
一种方法,它将优雅地处理文件名中的空格:
files=("$dir"/*); files=("${files[@]/#"$dir"\//"$prefix"}")
这会将前缀字符串存储在数组$files
中;你可以使用数组扩展迭代它们:
for file in "${files[@]}"; do
# Something with file
done
或使用printf
打印出来:
printf "%s\n" "${files[@]}"
使用数组扩展的优点是它不涉及分词,所以即使元素中有空格,数组扩展也会将每个元素都包含在一个单词中。
答案 2 :(得分:0)
当然,bash可以做到。
让我们一步一步来。
1。在第二个示例中解决问题
这是您的第二个示例
echo string{$(ls some_dir) | tr ' ' ','}
您将管道放在命令替换之外,这是完全错误的。
我相信您希望将流从ls
输出流传输到tr
输入流,因此很明显,该管道应该放在命令替换中,像这样
echo string{$(ls some_dir | tr ' ' ',')}
2。 ls
的输出用换行符代替,而不是空格
所以我们开始
echo string{$(ls some_dir | tr '\n' ',')}
3。大括号扩展是在命令替换之前执行的
换句话说,将命令替换扩展到f1,f2,f3,d1,
之后,将不再执行大括号扩展。
因此,毫无疑问,该命令将显示string{f1,f2,f3,d1,}
。
解决方案是让bash再次对其进行评估。
eval echo string{$(ls some_dir | tr '\n' ',')}
好的,到目前为止,结果看起来非常好(尝试一下,您会得到的),它非常接近您想要的东西,除了一个小地方。
您可能已经在我上面展示的输出末尾注意到了逗号。逗号导致不必要的string
出现在最终输出的末尾。
让我们完成它。
4。删除结尾的逗号
eval echo string{$(echo -n "$(ls some_dir)" | tr '\n' ',')}
好的,就是这样。
哦...顺便说一句,这只是针对您特定问题的特定解决方案。您可能会开发新的问题变体,而这种特定的解决方案可能不适合您的新问题。如果是这样,我建议您运行man bash
,并非常仔细地从头到脚阅读,那么您将变得势不可挡。