Bash 如何将shell扩展返回的每个单词打印在单独的行上?

Bash 如何将shell扩展返回的每个单词打印在单独的行上?,bash,shell,Bash,Shell,当我们使用shell展开时,它在一行中给出所有展开的单词。例如: #!/bin/bash data="Hello\ {World,Rafi}" eval echo $data 这将产生以下输出: Hello World Hello Rafi 可以这样在单独的行上输出每一行吗 你好,世界 你好,拉菲 echo-e将评估换行符。实际上,您的问题不是扩展,而是echo命令。根据您的系统,您可以通过 #!/bin/bash data="Hello\ {World\\\\n,Rafi}" eval

当我们使用shell展开时,它在一行中给出所有展开的单词。例如:

#!/bin/bash 
data="Hello\ {World,Rafi}"
eval echo $data
这将产生以下输出:

Hello World Hello Rafi
可以这样在单独的行上输出每一行吗

你好,世界
你好,拉菲

echo-e将评估换行符。

实际上,您的问题不是扩展,而是
echo
命令。根据您的系统,您可以通过

#!/bin/bash
data="Hello\ {World\\\\n,Rafi}"
eval echo -e "$data"

这是不同的解决方案,但非常干净

#!/bin/bash

names="World Rafi"
for name in $names
do
    echo Hello $name
done

和安塔鲁斯的答案一样,只是echo有“-n”。从

-n不输出尾随的换行符


如果我理解的没错,您希望使用大括号扩展(
{…}
)生成多个单词,然后将每个单词打印在单独的行上

如果您不一定要在变量中存储
“Hello\{World,Rafi}”
,您可以使用
printf
shell内置来实现这一点

printf "%s\n" "Hello "{Rafi,World}

一些解释: 格式字符串(此处:
%s\n
)将重复使用,直到
printf
的所有参数用完()

  • %s\n
    使用1个参数

  • “Hello”{Rafi,World}
    返回两个单词/参数,即
    “Hello Rafi”
    “Hello World”

  • 因此,这个
    printf
    命令相当于

     printf "%s\n%s\n" "Hello Rafi" "Hello World"
    
    不过你不必把这些都打出来


  • 另一种策略是使用数组,而不是使用
    eval
    (这是一种危险的做法,实际上不是一种好的做法——请参阅我在你文章中的评论)。以下内容将以干净、安全的方式完全满足您的要求:

    data=( "Hello "{World,Rafi} )
    printf "%s\n" "${data[@]}"
    

    谢谢,它可以工作:)但它也会在行首打印一个额外的换行符,如果我移动换行符的末尾(`Hello\{World,Rafi}'\n')从第二行开始添加了一个额外的空格。有什么解决方法吗?@Rafi我已经编辑了答案。在每个单词的末尾添加了新行字符。如果不需要,请跳过添加。甚至在{World,Rafi}中为name添加
    ;不要因为没有提到
    eval
    ,而使用…
    +1
    。您在这里没有正确使用bash。
    eval
    是邪恶的,尤其是当您没有意识到它的邪恶时!例如,如果
    data='Hello;ls'
    ,请尝试
    eval echo“$data”
    你会有一个惊喜。现在想想这样的情况,
    ls
    被一个邪恶的命令所取代,例如,
    rm-rf。
    …你绝对应该重新考虑你的策略!非常感谢。我从来没有这样想过。
    +1
    因为没有提到
    eval
     printf "%s\n%s\n" "Hello Rafi" "Hello World"
    
    data=( "Hello "{World,Rafi} )
    printf "%s\n" "${data[@]}"