Linux 尝试在 bash 中的变量中嵌入换行符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9139401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:22:52  来源:igfitidea点击:

Trying to embed newline in a variable in bash

linuxbash

提问by Ankur Agarwal

I have

我有

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

I want last echo to print

我想打印最后一个回声

a
b
c

Notice that I want the variable p to contain newlines. How do I do that?

请注意,我希望变量 p 包含换行符。我怎么做?

采纳答案by olibre

Summary

概括

  1. Inserting \n

    p="${var1}\n${var2}"
    echo -e "${p}"
    
  2. Inserting a new line in the source code

    p="${var1}
    ${var2}"
    echo "${p}"
    
  3. Using $'\n'(only bashand zsh)

    p="${var1}"$'\n'"${var2}"
    echo "${p}"
    
  1. 插入 \n

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

    p="${var1}
    ${var2}"
    echo "${p}"
    
  3. 使用$'\n'(仅bashzsh

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

Details

细节

1. Inserting \n

1. 插入 \n

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

echo -einterprets the two characters "\n"as a new line.

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

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

Avoid extra leading newline

避免额外的前导换行符

var="a b c"
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

Using a function

使用函数

embed_newline()
{
   local p=""
   shift
   for i in "$@"
   do
      p="$p\n$i"         # Append
   done
   echo -e "$p"          # Use -e
}

var="a b c"
p=$( embed_newline $var )  # Do not use double quotes "$var"
echo "$p"

2. Inserting a new line in the source code

2.在源代码中插入新行

var="a b c"
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

Avoid extra leading newline

避免额外的前导换行符

var="a b c"
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

Using a function

使用函数

embed_newline()
{
   local p=""
   shift
   for i in "$@"
   do
      p="$p
$i"                      # Append
   done
   echo "$p"             # No need -e
}

var="a b c"
p=$( embed_newline $var )  # Do not use double quotes "$var"
echo "$p"

3. Using $'\n'(less portable)

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

bashand zshinterprets $'\n'as a new line.

bashzsh解释$'\n'为一个新行。

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

Avoid extra leading newline

避免额外的前导换行符

var="a b c"
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

Using a function

使用函数

embed_newline()
{
   local p=""
   shift
   for i in "$@"
   do
      p="$p"$'\n'"$i"    # Append
   done
   echo "$p"             # No need -e
}

var="a b c"
p=$( embed_newline $var )  # Do not use double quotes "$var"
echo "$p"

Output is the same for all

输出对所有人都一样

a
b
c

Special thanks to contributors of this answer: kevinf, Gordon Davisson, l0b0, Dolda2000and tripleee.

特别感谢这个答案的贡献者:kevinfGordon Davissonl0b0Dolda2000triplee



EDIT

编辑

回答by Dolda2000

Try echo $'a\nb'.

试试echo $'a\nb'

If you want to store it in a variable and then use it with the newlines intact, you will have to quote your usage correctly:

如果要将其存储在变量中,然后将其与完整的换行符一起使用,则必须正确引用您的用法:

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

Or, to fix your example program literally:

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

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

回答by tripleee

The trivial solution is to put those newlines where you want them.

简单的解决方案是将这些换行符放在您想要的位置。

var="a
b
c"

Yes, that's an assignment wrapped over multiple lines.

是的,这是一个包含在多行中的赋值。

However, you will need to double-quote the value when interpolating it, otherwise the shell will split it on whitespace, effectively turning each newline into a single space (and also expand any wildcards).

但是,您需要在插入值时用双引号引用该值,否则 shell 会将其拆分为空格,从而有效地将每个换行符转换为一个空格(并扩展任何通配符)。

echo "$p"

Generally, you should double-quote all variable interpolations unless you specifically desire the behavior described above.

通常,除非您特别需要上述行为,否则您应该双引号引用所有变量插值。

回答by Ankur Agarwal

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

The solution was simply to protect the inserted newline with a "" during current iteration when variable substitution happens.

解决方案只是在发生变量替换时在当前迭代期间用“”保护插入的换行符。

回答by 0xAX

sedsolution:

sed解决方案:

echo "a b c" | sed 's/ \+/\n/g'

Result:

结果:

a
b
c

回答by yoshi kakbudto

there is no need to use for cycle

无需使用 for 循环

you can benefit from bash parameter expansion functions:

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

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

or just use tr:

或者只使用 tr:

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

回答by yoshi kakbudto

There are three levels at which a newline could be inserted in a variable.
Well ..., technically four, but the first two are just two ways to write the newline in code.

可以在三个级别上在变量中插入换行符。
嗯...,技术上有四种,但前两种只是在代码中编写换行符的两种方法。

1.1. At creation.

1.1. 创作时。

The most basic is to create the variable with the newlines already.
We write the variable value in code with the newlines already inserted.

最基本的是创建带有换行符的变量。
我们在已经插入换行符的代码中编写变量值。

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

Or, inside an script code:

或者,在脚本代码中:

var="a
b
c"

Yes, that means writing Enterwhere needed in the code.

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

1.2. Create using shell quoting.

1.2. 使用 shell 引用创建。

The sequence $'is an special shell expansion in bash and zsh.

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

var=$'a\nb\nc'

The line is parsed by the shell and expanded to ? var="anewlinebnewlinec" ?, which is exactly what we want the variable var to be.
That will notwork on older shells.

该行由 shell 解析并扩展为 ? var="a newlineb newlinec" ?,这正是我们想要的变量 var。
不适用于较旧的外壳。

2. Using shell expansions.

2. 使用外壳扩展。

It is basically a command expansion with several commands:

它基本上是一个带有几个命令的命令扩展:

  1. echo -e

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

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

    printf -v var '%b' "a\nb\nc"
    
  4. Plain simple printf (works on most shells):

    var="$( printf 'a\nb\nc' )"
    
  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. Using shell execution.

3.使用shell执行。

All the commands listed in the second option could be used to expand the value of a var, if that var contains special characters.
So, all we need to do is get those values inside the var and execute some command to show:

如果 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.

Note that printf is somewhat unsafe if var value is controlled by an attacker.

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