简体   繁体   中英

How can I print a newline as \n in bash?

Basically I want to achieve something like the inverse of echo -e . I have a variable which stores a command output but I want to print newlines as \\n.

这是我的解决方案:

sed 's/$/\\n/' | tr -d '\n'

If your input is already in a ( bash ) shell variable , say $varWithNewlines :

echo "${varWithNewlines//$'\n'/\\n}"

Simply uses bash parameter expansion to replace all newline ( $'\\n' ) instances with literal '\\n' each.


If your input comes from a file , use awk :

awk -v ORS='\\n' 1

In action, with sample input:

# Sample input with actual newlines created with ANSI C quoting ($'...'), 
# which turns `\n` literals into actual newlines.
varWithNewlines=$'line 1\nline 2\nline 3'

# Translate newlines to '\n' literals.
# Note the use of `printf %s` to avoid adding an additional newline.
# By contrast, a here-string - <<<"$varWithNewlines" _always appends a newline_.
printf %s "$varWithNewlines" | awk -v ORS='\\n' 1
  • awk reads input line by line
  • by setting ORS - the output record separator to literal '\\n' (escaped with an additional \\ so that awk doesn't interpret it as an escape sequence), the input lines are output with that separator
  • 1 is just shorthand for {print} , ie, all input lines are printed, terminated by ORS .

Note: The output will always end in literal '\\n' , even if your input does not end in a newline .
This is because awk terminates every output line with ORS , whether the input line ended with a newline (separator specified in FS ) or not.


Here's how to unconditionally strip the terminating literal '\\n' from your output.

# Translate newlines to '\n' literals and capture in variable.
varEncoded=$(printf %s "$varWithNewlines" | awk -v ORS='\\n' 1)

# Strip terminating '\n' literal from the variable value 
# using bash parameter expansion.
echo "${varEncoded%\\n}" 

By contrast, more work is needed if you want to make the presence of a terminating literal '\\n' dependent on whether the input ends with a newline or not .

# Translate newlines to '\n' literals and capture in variable.
varEncoded=$(printf %s "$varWithNewlines" | awk -v ORS='\\n' 1)

# If the input does not end with a newline, strip the terminating '\n' literal.
if [[ $varWithNewlines != *$'\n' ]]; then 
  # Strip terminating '\n' literal from the variable value 
  # using bash parameter expansion.
  echo "${varEncoded%\\n}"
else 
  echo "$varEncoded"
fi

You can use printf "%q" :

eol=$'\n'
printf "%q\n" "$eol"
$'\n'

A Bash solution

x=$'abcd\ne fg\nghi'
printf "%s\n" "$x"
abcd
e fg
ghi
y=$(IFS=$'\n'; set -f; printf '%s\\n' $x)
y=${y%??}
printf "%s\n" "$y"
abcd\ne fg\nghi

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM