bash打印转义文件内容

时间:2016-07-08 18:39:08

标签: bash printf cat

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

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

例如,如果我的文件是

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

它应该打印

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

我试图使用带有%q格式说明符的printf,但是它存在删除尾随空格的问题。

3 个答案:

答案 0 :(得分:5)

只做你明确要求的两个文字转换:

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

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

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

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

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

答案 1 :(得分:2)

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

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"

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

答案 2 :(得分:2)

在我看来,将任意多行文本转换为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

这样做的好处是可以处理所有字符,包括CR和标签,而不仅仅是换行符。

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

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