bash 中的 Printf 示例不会创建换行符

问题描述 投票:0回答:9

在 bash 脚本中使用

printf
,在
"\n"
之后不添加空格不会创建换行符,而添加空格会创建换行符,例如。例:

  1. "\n"

    之后没有空格
    NewLine=`printf "\n"`
    echo -e "Firstline${NewLine}Lastline"
    

    结果:

    FirstlineLastline
    
  2. "\n "

    之后有空格
    NewLine=`printf "\n "`
    echo -e "Firstline${NewLine}Lastline"
    

    结果:

    Firstline
     Lastline
    

问题:为什么 1. 没有创建以下结果:

Firstline 
Lastline

我知道这个具体问题可以使用其他技术来解决,但我想重点讨论为什么 1. 不起作用。

编辑: 当使用 echo 而不是 printf 时,我得到了预期的结果,但为什么 printf 的工作方式不同?

    NewLine=`echo "\n"`
    echo -e "Firstline${NewLine}Lastline"

结果:

    Firstline
    Lastline
bash printf
9个回答
36
投票

反引号运算符删除尾随的新行。参见3.4.5。命令替换位于 http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html

编辑问题的注释

比较:

[alvaro@localhost ~]$ printf "\n"

[alvaro@localhost ~]$ echo "\n"
\n
[alvaro@localhost ~]$ echo -e "\n"


[alvaro@localhost ~]$

echo 命令不会将

\n
视为换行符,除非你告诉他这样做:

NAME
       echo - display a line of text
[...]
       -e     enable interpretation of backslash escapes

POSIX 7 指定了此行为此处

[...] 使用命令的标准输出,删除替换末尾的一个或多个字符的序列


9
投票

也许人们会遇到和我一样的问题: 回声 在用背棍包裹的代码内。一个小提示:

printf "astring\n"
# and 
printf "%s\n" "astring" 
# both have the same effect.
# So... I prefer the less typing one

简短的回答是:

# Escape \n correctly !

# Using just: printf "$myvar\n" causes this effect inside the backsticks:
printf "banana
"

# So... you must try \\n  that will give you the desired 
printf "banana\n"

# Or even \\\\n if this string is being sent to another place 
# before echoing,

buffer="${buffer}\\\\n printf \"$othervar\\\\n\""

一个常见的问题是,如果您在代码中执行以下操作:

echo 'Tomato is nice'

当被反棍包围时会产生错误

command Tomato not found.

解决方法是添加另一个 echo -e 或 printf

printed=0

function mecho(){
  #First time you need an "echo" in order bash relaxes.
  if [[ $printed == 0 ]]; then
    printf "echo -e $1\\\\n"
    printed=1
  else
    echo -e "\r\n\r$1\\\\n"
  fi
}

现在您可以在提示中调试代码:

(prompt)$  `mySuperFunction "arg1" "etc"`

输出会很好

 mydebug: a value
 otherdebug: whathever appended using myecho
 a third string

并使用

进行内部调试
mecho "a string to be hacktyped"

6
投票
$ printf -v NewLine "\n"
$ echo -e "Firstline${NewLine}Lastline"

Firstline
Lastline

$ echo "Firstline${NewLine}Lastline"
Firstline
Lastline

4
投票

看起来 BASH 正在删除尾随换行符。 例如

NewLine=`printf " \n\n\n"`
echo -e "Firstline${NewLine}Lastline"
Firstline Lastline

NewLine=`printf " \n\n\n "`
echo -e "Firstline${NewLine}Lastline"
Firstline


 Lastline

4
投票

您编辑的

echo
版本将文字反斜杠-n放入变量
$NewLine
中,然后由您的
echo -e
解释。如果你这样做:

NewLine=$(echo -e "\n")
echo -e "Firstline${NewLine}Lastline"

您的结果将与情况 #1 相同。要使 that 能够以这种方式工作,您必须转义反斜杠并将整个内容放在单引号中:

NewLine=$(printf '\\n')
echo -e "Firstline${NewLine}Lastline"

或双重转义它:

NewLine=$(printf "\\\n")

当然,你可以直接使用

printf
或者你可以像这样设置你的 NewLine 值:

printf "Firstline\nLastline\n"

NewLine=$'\n'
echo "Firstline${NewLine}Lastline"    # no need for -e

4
投票

对于来这里想知道如何在

printf
的参数中使用换行符的人,请使用
%b
而不是
%s

$> printf "a%sa" "\n"
a\na
$> printf "a%ba" "\n"
a
a

来自手册:

%b 在相应的参数中展开反斜杠转义序列


1
投票

我们不需要“echo”或“printf”来创建 NewLine 变量:

NewLine="
"
printf "%q\n" "${NewLine}"
echo "Firstline${NewLine}Lastline"

0
投票

Bash 删除命令替换中所有尾随换行符。

要保存尾随换行符,请使用

printf
printf -v VAR

输出分配给变量

而不是

NewLine=`printf "\n"`
echo -e "Firstline${NewLine}Lastline"
#FirstlineLastline

使用

printf -v NewLine '\n'
echo -e "Firstline${NewLine}Lastline"
#Firstline
#Lastline

说明

根据bash man的说法

3.5.4 命令替换

$(命令)

`命令`

Bash 通过执行命令 并将命令替换替换为命令的标准输出,删除所有尾随换行符来执行扩展。嵌入的换行符不会被删除,但在分词过程中可能会被删除。

因此,在添加任何尾随换行符后,bash 将删除它们。

var=$(printf '%s\n%s\n\n\n' 'foo' 'bar')
echo "$var"

输出:

foo
bar

根据

help printf

printf [-v var] format [arguments]

如果提供了 -v 选项,则输出将放入 shell 变量 VAR 的值中,而不是发送到标准输出。

在这种情况下,为了将格式化文本安全复制到变量,请使用

[-v var]
选项:

printf -v var '%s\n%s\n\n\n' 'foo' 'bar'
echo "$var"

输出:

foo
bar





-3
投票

如果添加“则可以正常工作 ”

$ nl=`printf "

“` && 回显“1${nl}2”
1
2
© www.soinside.com 2019 - 2024. All rights reserved.