尝试embedded换行variables在bash中

我有

var="abc" for i in $var do p=`echo -e $p'\n'$i` done echo $p 

我想要最后一个回显打印

 a b c 

注意我想让variablesp包含换行符。 我怎么做?

概要

  1. 插入\n

     p="${var1}\n${var2}" echo -e "${p}" 
  2. 在源代码中插入一个新行

     p="${var1} ${var2}" echo "${p}" 
  3. 使用$'\n' (只有bash和zsh )

     p="${var1}"$'\n'"${var2}" echo "${p}" 

细节

1.插入\n

 p="${var1}\n${var2}" echo -e "${p}" 

echo -e将两个字符"\n"为新行。

 var="abc" first_loop=true for i in $var do p="$p\n$i" # Append unset first_loop done echo -e "$p" # Use -e 

避免额外的领先换行符

 var="abc" first_loop=1 for i in $var do (( $first_loop )) && # "((...))" is bash specific p="$i" || # First -> Set p="$p\n$i" # After -> Append unset first_loop done echo -e "$p" # Use -e 

使用一个函数

 embed_newline() { local p="$1" shift for i in "$@" do p="$p\n$i" # Append done echo -e "$p" # Use -e } var="abc" p=$( embed_newline $var ) # Do not use double quotes "$var" echo "$p" 

2.在源代码中插入一个新行

 var="abc" for i in $var do p="$p $i" # New line directly in the source code done echo "$p" # Double quotes required # But -e not required 

避免额外的领先换行符

 var="abc" first_loop=1 for i in $var do (( $first_loop )) && # "((...))" is bash specific p="$i" || # First -> Set p="$p $i" # After -> Append unset first_loop done echo "$p" # No need -e 

使用一个函数

 embed_newline() { local p="$1" shift for i in "$@" do p="$p $i" # Append done echo "$p" # No need -e } var="abc" p=$( embed_newline $var ) # Do not use double quotes "$var" echo "$p" 

3.使用$'\n' (不太便携)

bash和zsh将$'\n'为新行。

 var="abc" for i in $var do p="$p"$'\n'"$i" done echo "$p" # Double quotes required # But -e not required 

避免额外的领先换行符

 var="abc" first_loop=1 for i in $var do (( $first_loop )) && # "((...))" is bash specific p="$i" || # First -> Set p="$p"$'\n'"$i" # After -> Append unset first_loop done echo "$p" # No need -e 

使用一个函数

 embed_newline() { local p="$1" shift for i in "$@" do p="$p"$'\n'"$i" # Append done echo "$p" # No need -e } var="abc" p=$( embed_newline $var ) # Do not use double quotes "$var" echo "$p" 

所有的输出都是一样的

 a b c 

特别感谢这个答案的贡献者: kevinf , Gordon Davisson , l0b0 , Dolda2000和tripleee 。


编辑

  • 另请参阅BinaryZebra的答案,提供许多细节。
  • Abhijeet Rastogi的答案和Dimitry的答案解释了如何避免上面的bash片段中的for循环。

微不足道的解决scheme是把这些换行符放在你想要的地方。

 var="a b c" 

是的,这是一个包含多行的任务。

但是,插入时需要双引号,否则shell会将其分割为空格,从而有效地将每个换行符转换为单个空格(并扩展通配符)。

 echo "$p" 

一般来说,除非特别需要上述行为,否则应该对所有variables插值进行双引号。

试试echo $'a\nb'

如果你想把它存储在一个variables中,然后用换行符完整地使用它,那么你必须正确引用你的用法:

 var=$'a\nb\nc' echo "$var" 

或者,从字面上修复您的示例程序:

 var="abc" for i in $var; do p="`echo -e "$p\\n$i"`" done echo "$p" 

有三个层次可以在一个variables中插入换行符。
嗯,从技术上讲,四,但前两个只是两种方式来编写代码换行符。

1.1。 在创作。

最基本的是用newlines创buildvariables。
我们用已经插入的换行符在代码中编写variables值。

 $ var="a > b > c" $ echo "$var" a b c 

或者,在脚本代码中:

 var="a b c" 

是的,这意味着在代码中需要的地方写入Enter

1.2。 创build使用shell引用。

序列$ '是bash和zsh中的一个特殊的shell扩展。

 var=$'a\nb\nc' 

该行由shellparsing并扩展为“var =” newline b newline c“»,这正是我们想要的variablesvar。
这对旧的shell不起作用。

2.使用shell扩展。

这基本上是一个命令扩展与几个命令:

  1. 回声-e

     var="$( echo -e "a\nb\nc" )" 
  2. bash和zsh printf'%b'

     var="$( printf '%b' "a\nb\nc" )" 
  3. bash printf -v

     printf -v var '%b' "a\nb\nc" 
  4. 简单的printf(适用于大多数shell):

     var="$( printf 'a\nb\nc' )" 

3.使用shell执行。

如果该var包含特殊字符,则第二个选项中列出的所有命令都可用于扩展var的值。
所以,我们需要做的就是在var内部获取这些值,并执行一些命令来显示:

 var="a\nb\nc" # var will contain the characters \n not a newline. echo -e "$var" # use echo. printf "%b" "$var" # use bash %b in printf. printf "$var" # use plain printf. 

请注意,如果var值由攻击者控制,则printf会有些不安全。

没有必要使用循环

您可以从bash参数扩展函数中受益:

 var="abc"; var=${var// /\\n}; echo -e $var a b c 

或者只是使用tr:

 var="abc" echo $var | tr " " "\n" a b c 

sed解决scheme:

 echo "abc" | sed 's/ \+/\n/g' 

结果:

 a b c 
 var="abc" for i in $var do p=`echo -e "$p"'\n'$i` done echo "$p" 

该解决scheme仅仅是在variablesreplace发生时在当前迭代期间用“”来保护插入的换行符。