使用 sed (或 awk、或 tr)将换行符 \n 替换为表达式

use*_*237 2 awk grep sed tr

我正在尝试清理伪 json 文件的语法。该文件太大,无法在文本编辑器中打开(20 GB),因此我必须通过命令行(运行 Arch linux)来完成所有这些操作。我不知道该怎么做的一件事是替换 sed 中的换行符(GNU sed v. 4.8)

具体来说,我有以下形式的数据:

{
    "id" : 1,
    "value" : 2
}
{
    "id" : 2,
    "value" : 4
}
Run Code Online (Sandbox Code Playgroud)

我需要在闭花括号后面加一个逗号(但不是最后一个)。所以我希望输出看起来像:

{
    "id" : 1,
    "value" : 2
},
{
    "id" : 2,
    "value" : 4
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,我只是在 中执行此操作sed,但从阅读到此内容,sed 首先将文本展平,因此不清楚如何替换换行符。理想情况下,我只是运行类似的东西sed 's/}\n{/},\n{/g' test.json,但这不起作用(使用 \\n 代替 \n 也不起作用)。

我也尝试过 awk,但遇到了类似的问题,无法替换硬回车与括号的组合。我可以用 tr 来替换硬回车,但不能用字符组合。

关于如何解决这个问题有什么想法吗?

Sun*_*eep 5

是的,默认情况下sed逐行工作。除非使用功能将多行引入模式空间,否则无法跨多行进行匹配。这是一种方法,前提是输入严格遵循所示示例:

sed '/}$/{N; s/}\n{/},\n{/}' ip.txt
Run Code Online (Sandbox Code Playgroud)
  • /}$/匹配}在行尾
    • {}允许您对要为特定地址执行的命令进行分组
    • N将下一行添加到模式空间
    • s/}\n{/},\n{/执行所需的替换
  • 使用-i就地编辑选项

对于如下所示的序列,此解决方案可能会失败,但我假设以 结尾的两行}不会连续出现。

}
}
{
abc
}
Run Code Online (Sandbox Code Playgroud)

sed '/}$/{N; s/}\n{/},\n{/; P; D}'如果上述序列可能发生,则使用。