如何在Bash中将多行文件转换为带有换行符的字符串?

6

我该如何在Bash中将多行��件转换为带有\n字符的字符串?

例如 - 我有一个证书需要配置在我的配置JSON文件中,所以不要让它像这样:

-----BEGIN CERTIFICATE-----
MIIDBjCCMIIDB
MIIDBjCCMIIDB
    .... 
MIIDBjCCMIIDB==
-----END CERTIFICATE-----

我将会有

-----BEGIN CERTIFICATE-----\nMIIDBjCCMIIDB\nMIIDBjCCMIIDB\n....\nMIIDBjCCMIIDB==\n-----END CERTIFICATE-----

逐行读取文件并将读取的数据附加到一个变量中。 - msrd0
@AvinashRaj - 我承认我的例子不够准确。省略号代表该行之前和之后的内容。对我来说,问题足够清晰,因为我没有收到不好的反馈。 - guy mograbi
你的期望输出展示了你的需求,但是 如何在bash中将多行文件转换为带有 \n 字符的字符串? 这一行则表达了不同的意思。 - Avinash Raj
4个回答

11

使用 awk 的一种方法:

$ awk '$1=$1' ORS='\\n' file
-----BEGIN CERTIFICATE-----\nMIIDBjCCMIIDB\nMIIDBjCCMIIDB\n....\nMIIDBjCCMIIDB==\n-----END CERTIFICATE-----\n

如果似乎无法正常工作,请仔细检查文件的行尾。您可以通过首先运行文件通过 dos2unix 来断言行尾是 Unix 友好的。 一行解决方案看起来像:cat file | dos2unix | awk '$1=$1' ORS='\\n' /dev/stdin - Miron Veryanskiy

1

这是一个纯bash(需要Bash≥4)的解决方案,应该相当高效:

mapfile -t lines_ary < file
printf -v cert '%s\\n' "${lines_ary[@]}"

检查它是否正常工作:

echo "$cert"

需要注意的是,你会在结尾处得到一个换行符\n。如果这不是问题,那么使用这种方法就可以了。否则,在printf -v语句之后添加以下代码即可去除它:

cert=${cert%\\n}

1

Bash具有简单的字符串替换功能。

cert=$(cat file)
echo "${cert//$'\n'/\\n}"

在替换部分,我最初将 '\n' 用单引号括起来,但基于对 Bash 3.2.39(1) 的测试,我将它们去掉了(是的,这有点旧)。


这正是我需要的!只有一个更正... 应该是 \n 而不是 \n。否则它将无法工作... 所以变成 ===> echo "${cert//$'\n'/\n}" - Macindows
@Macindows 对我来说两种方式都可以,但是根据你的反馈,我添加了第二个反斜杠。我仍然在使用Bash 3.2.57(1)(原始macOS Catalina)。谢谢。 - tripleee

0

另一种awk解决方案,

$ awk -v RS= '{gsub(/\n+/, "\\n")}1' file
-----BEGIN CERTIFICATE-----\nMIIDBjCCMIIDB\nMIIDBjCCMIIDB\n    .... \nMIIDBjCCMIIDB==\n-----END CERTIFICATE-----

通过 sed,

$ sed ':a;N;$!ba;s/\n/\\n/g' file
-----BEGIN CERTIFICATE-----\nMIIDBjCCMIIDB\nMIIDBjCCMIIDB\n    .... \nMIIDBjCCMIIDB==\n-----END CERTIFICATE-----

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接