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

Ank*_*wal 92 linux bash

我有

var="a b c"
for i in $var
do
   p=`echo -e $p'\n'$i`
done
echo $p
Run Code Online (Sandbox Code Playgroud)

我想要打印最后一个回声

a
b
c
Run Code Online (Sandbox Code Playgroud)

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

oli*_*bre 153

摘要

  1. 插入 \n

    p="${var1}\n${var2}"
    echo -e "${p}"
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在源代码中插入新行

    p="${var1}
    ${var2}"
    echo "${p}"
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用$'\n'(仅限)

    p="${var1}"$'\n'"${var2}"
    echo "${p}"
    
    Run Code Online (Sandbox Code Playgroud)

细节

1.插入 \n

p="${var1}\n${var2}"
echo -e "${p}"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

避免额外的领先换行

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
Run Code Online (Sandbox Code Playgroud)

使用功能

embed_newline()
{
   local p="$1"
   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"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

避免额外的领先换行

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
Run Code Online (Sandbox Code Playgroud)

使用功能

embed_newline()
{
   local p="$1"
   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"
Run Code Online (Sandbox Code Playgroud)

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

解释$'\n'为新行.

var="a b c"
for i in $var
do
   p="$p"$'\n'"$i"
done
echo "$p" # Double quotes required
          # But -e not required
Run Code Online (Sandbox Code Playgroud)

避免额外的领先换行

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
Run Code Online (Sandbox Code Playgroud)

使用功能

embed_newline()
{
   local p="$1"
   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"
Run Code Online (Sandbox Code Playgroud)

输出对所有人来说都是一样的

a
b
c
Run Code Online (Sandbox Code Playgroud)

特别感谢这个答案的贡献者:kevinf,Gordon Davisson,l0b0,Dolda2000tripleee.


编辑

  • 这实际上没有嵌入换行符,它嵌入了`\n`,`echo -e`在打印时转换为换行符.根据您的实际目标,这可能会也可能不会. (11认同)

tri*_*eee 21

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

var="a
b
c"
Run Code Online (Sandbox Code Playgroud)

是的,这是一个包含多行的作业.

但是,在插值时需要对值进行双引号,否则shell会将其拆分为空白,有效地将每个换行符转换为单个空格(并展开任何通配符).

echo "$p"
Run Code Online (Sandbox Code Playgroud)

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


Dol*_*000 12

试试echo $'a\nb'.

如果要将其存储在变量中,然后将其与新行保持一致使用,则必须正确引用您的用法:

var=$'a\nb\nc'
echo "$var"
Run Code Online (Sandbox Code Playgroud)

或者,按字面意思修复示例程序:

var="a b c"
for i in $var; do
    p="`echo -e "$p\\n$i"`"
done
echo "$p"
Run Code Online (Sandbox Code Playgroud)


小智 10

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

1.1.在创作.

最基本的是使用换行符创建变量.
我们在代码中使用已插入的换行符编写变量值.

$ var="a
> b
> c"
$ echo "$var"
a
b
c
Run Code Online (Sandbox Code Playgroud)

或者,在脚本代码中:

var="a
b
c"
Run Code Online (Sandbox Code Playgroud)

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

1.2.使用shell引用创建.

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

var=$'a\nb\nc'
Run Code Online (Sandbox Code Playgroud)

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

2.使用shell扩展.

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

  1. 回声-e

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

    var="$( printf '%b' "a\nb\nc" )"
    
    Run Code Online (Sandbox Code Playgroud)
  3. bash printf -v

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

    var="$( printf 'a\nb\nc' )"
    
    Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

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


yos*_*dto 5

无需使用 for 循环

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

var="a b c"; 
var=${var// /\\n}; 
echo -e $var
a
b
c
Run Code Online (Sandbox Code Playgroud)

或者只使用 tr:

var="a b c"
echo $var | tr " " "\n"
a
b
c
Run Code Online (Sandbox Code Playgroud)