bash 打印转义文件内容



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

# 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"

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

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

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)"

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

printf 'nnfoonn' > file
contents="$(cat "file"; printf x)"
contents="${contents%x}"
printf "The shell equivalent of the file contents is: %qn" "$contents"

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

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新