我如何在sh中的string中换行?

这个

STR="Hello\nWorld" echo $STR 

产生作为输出

 Hello\nWorld 

代替

 Hello World 

我应该怎么做一个string换行符?

注意: 这个问题不是关于回声 我知道echo -e ,但我正在寻找一种解决scheme,允许将string(包括换行符)作为parameter passing给其他没有类似选项的命令来将\n作为换行符来解释。

解决方法是使用$'string' ,例如:

 $ STR=$'Hello\nWorld' $ echo "$STR" Hello World 

以下是Bash手册页的摘录:

  Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows: \a alert (bell) \b backspace \e \E an escape character \f form feed \n new line \r carriage return \t horizontal tab \v vertical tab \\ backslash \' single quote \" double quote \nnn the eight-bit character whose value is the octal value nnn (one to three digits) \xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) \cx a control-x character The expanded result is single-quoted, as if the dollar sign had not been present. A double-quoted string preceded by a dollar sign ($"string") will cause the string to be translated according to the current locale. If the current locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted. 

回声是如此九十年代充满危险,它的使用应导致核心倾倒不低于4GB。 严重的是,echo的问题是为什么Unix标准化过程最终发明了printf工具,并解决了所有的问题。

所以要得到一个string换行符:

 FOO="hello world" BAR=$(printf "hello\nworld\n") # Alternative; note: final newline is deleted printf '%s\n' "$FOO" printf '%s\n' "$BAR" 

那里! 没有SYSV与BSD的回声疯狂,一切都得到整齐打印和完全便携式支持C转义序列。 现在大家请使用printf ,永远不要回头。

我根据其他答案做了什么

 NEWLINE=$'\n' my_var="__between eggs and bacon__" echo "spam${NEWLINE}eggs${my_var}bacon${NEWLINE}knight" # which outputs: spam eggs__between eggs and bacon__bacon knight 

问题不在于shell。 问题实际上是使用echo命令本身,并且在variables插值周围缺less双引号。 您可以尝试使用echo -e但是在所有平台上都不支持,现在推荐使用printf来支持可移植性。

你也可以直接在shell脚本中插入换行符(如果脚本是你正在编写的),所以它看起来像…

 #!/bin/sh echo "Hello World" #EOF 

或等同地

 #!/bin/sh string="Hello World" echo "$string" # note double quotes! 
  1. 唯一简单的select是在variables中实际input一个新行:

     $ STR='new line' $ printf '%s' "$STR" new line 

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

  2. 有几个等同于一个new line字符。

     \n ### A common way to represent a new line character. \012 ### Octal value of a new line character. \x0A ### Hexadecimal value of a new line character. 

    但所有这些都需要一些工具( POSIX printf )来进行“解释”:

     echo -e "new\nline" ### on POSIX echo, `-e` is not required. printf 'new\nline' ### Understood by POSIX printf. printf 'new\012line' ### Valid in POSIX printf. printf 'new\x0Aline' printf '%b' 'new\0012line' ### Valid in POSIX printf. 

    因此,该工具需要用新行build立一个string:

     $ STR="$(printf 'new\nline')" $ printf '%s' "$STR" new line 
  3. 在某些shell中,序列$ '是一个特殊的shell扩展。 已知在ksh93,bash和zsh中工作:

     $ STR=$'new\nline' 
  4. 当然,更复杂的解决scheme也是可能的:

     $ echo '6e65770a6c696e650a' | xxd -p -r new line 

    要么

     $ echo "new line" | sed 's/ \+/\n/g' new line 

我发现-e旗优雅而直接

STR="Hello\nWorld" echo -e $STR #输出Hello World

如果string是另一个命令的输出,我只是使用引号

indexes_diff=$(git diff index.yaml) echo "$indexes_diff"

我不是bash专家,但是这个为我工作:

 STR1="Hello" STR2="World" NEWSTR=$(cat << EOF $STR1 $STR2 EOF ) echo "$NEWSTR" 

我发现这更容易格式化文本。

单引号之前的$ $如下所示'… \ n …',但双引号不起作用。

 $ echo $'Hello\nWorld' Hello World $ echo $"Hello\nWorld" Hello\nWorld 

在我的系统上(Ubuntu 17.10),你的例子只是按照需要工作,无论是从命令行input( sh )还是作为sh脚本执行:

 [bash]§ sh $ STR="Hello\nWorld" $ echo $STR Hello World $ exit [bash]§ echo "STR=\"Hello\nWorld\" > echo \$STR" > test-str.sh [bash]§ cat test-str.sh STR="Hello\nWorld" echo $STR [bash]§ sh test-str.sh Hello World 

我想这回答你的问题:它只是工作。 (我还没有试图弄清楚什么时候sh的换行符会在什么时候发生)。

不过,我注意到这个脚本在使用bash执行时会有不同的performance,而是会打印出Hello\nWorld

 [bash]§ bash test-str.sh Hello\nWorld 

我设法得到所需的输出与bash如下:

 [bash]§ STR="Hello > World" [bash]§ echo "$STR" 

注意$STR周围的双引号。 如果保存并作为bash脚本运行,则其行为相同。

以下也给出了所需的输出:

 [bash]§ echo "Hello > World"