bash 打印转义文件内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38273389/
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-09-18 14:52:34  来源:igfitidea点击:

bash print escaped file contents

bashprintfcat

提问by Petr Petrov

I'm trying to print the file contents with escaped double quotes.

我正在尝试使用转义的双引号打印文件内容。

# read file contents from ${filename}
# - escape double quotes
# - represent newlines as '\n' 
# print the result
echo "my file contents: \"${out}\""

So for example if my file is

例如,如果我的文件是

<empty line>
console.log("hello, world");
<empty line>

it should print

它应该打印

my file contents: "\nconsole.log(\"hello, world\");\n"

I was trying to use printf with %q format specifier, but had problems that it removes the trailing spaces.

我试图将 printf 与 %q 格式说明符一起使用,但遇到了删除尾随空格的问题。

回答by Charles Duffy

To do only the two literal transforms you've explicitly asked for:

仅执行您明确要求的两个文字转换:

IFS= read -r -d '' content <file
content=${content//'"'/'\"'/}
content=${content//$'\n'/'\n'}
echo "file contents: $content"

That said, if you're trying to represent arbitrary content as JSON strings, let a fully compliant JSON parser/generator do the heavy lifting:

也就是说,如果您尝试将任意内容表示为 JSON 字符串,让一个完全兼容的 JSON 解析器/生成器来完成繁重的工作:

IFS= read -r -d '' content <file
echo "file contents: $(jq -n --arg content "$content" '$content')"

...or, even better (to support even files with contents that bash can't store as a string), let jqread from the input file directly:

...或者,甚至更好(甚至支持 bash 无法存储为字符串的内容的文件),让我们jq直接从输入文件中读取:

echo "file contents: $(jq -Rs . <file)"

回答by that other guy

Command substitutions strip trailing line feeds. You can prevent this by adding a dummy non-linefeed character and then stripping it:

命令替换去除尾随换行符。您可以通过添加一个虚拟的非换行符然后剥离它来防止这种情况:

printf '\n\nfoo\n\n' > file

contents="$(cat "file"; printf x)"
contents="${contents%x}"

printf "The shell equivalent of the file contents is: %q\n" "$contents"

If you are trying to generate JSON, you should instead be using jq.

如果您尝试生成 JSON,则应该使用jq.

回答by ghoti

It seems to me that the most reliable way to convert arbitrary multiline text into printf formats would be to use printf, built in to bash.

在我看来,将任意多行文本转换为 printf 格式的最可靠方法是使用内置于 bash 的 printf。

$ nl -ba testfile
     1
     2  console.log("hello, world");
     3
$ s="$(printf '%q' "$(cat testfile; printf x)")"
$ s="${s%x\'}"; s="${s#$\'}"
$ echo "$s"
\nconsole.log("hello, world");\n\n

This has the advantage of handling allcharacters, including CRs and tabs rather than just newlines.

这具有处理所有字符的优点,包括 CR 和制表符,而不仅仅是换行符。

Note the fun command expansion workaround that we employ to avoid stripping the trailing newlines. (Otherwise, we could just s="$(printf '%q' "$(<testfile)")".)

请注意我们采用的 fun 命令扩展解决方法,以避免剥离尾随的换行符。(否则,我们只能s="$(printf '%q' "$(<testfile)")"。)

Note also the parameter expansion we do on the line before echo. This is required because of the way bash handles the %qformat character, returning a format-quoted string rather than just the formatted string.

还要注意我们在之前的行中进行的参数扩展echo。这是必需的,因为 bash 处理%q格式字符的方式,返回格式引用的字符串而不仅仅是格式化的字符串。