如何仅在文本文件不匹配此模式时才从文本文件中删除换行符 ]}\n 在 unix 中
how to remove newline from a text file only if it does not match this pattern ]}\n in unix
我是 oracle 和 unix 世界的新手,正在为这个问题苦苦挣扎。
我在一个文件中假脱机数据。 sql plus 的行大小限制为 32767,任何返回的大于该限制的数据记录都将换行到下一行。然后将创建的此文件上传到第三方服务,该第三方服务需要 json 格式的数据,仅在末尾有换行符,即在 }
之后
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
如果在假脱机数据时出现自动换行,则在每行之间插入一个 \n
字符,自动换行并中断此 json 数据。
我是否可以在这个假脱机文件中转义控制字符,如 \n
只有当它不在 }
之后出现时?
我可以使用任何 unix 命令吗?
任何帮助将不胜感激
TIA
在不太了解您的设置的情况下,一种选择是通过 sed 脚本传输文件,如下所示:
cat input.txt | sed -e ':start; /^{.*]}$/{p;d}; N;s/\n//g; b start;' > output.txt
这基本上是这样工作的:
- :start 创建一个分支标签跳转到
- /^{.*}$/{p;d} 查找 start/end 带有大括号的行,然后打印它们并移至下一行
- N 这只发生在上一行 NOT 找到匹配项,并读取下一行
- s/\n//g 删除所有换行符(不替换它们),
- b start 分支(跳转)回到起始标签
本质上它所做的是读取一行,检查它是否以大括号开始和结束。如果是,请打印并继续。如果没有,抓住下一行。当然,这假设 oracle 将始终输出以 { 开头并以 } 结尾的行(即大括号前后没有空格)。
模仿 this answer on a sister site,如果你在 Unix 中有你的假脱机文件,你可以将行与 awk
:
连接在一起
awk '{if (sub(/\]}$/,"")) printf "%s]}\n", [=10=]; else printf "%s", [=10=]}' yourfile.lis
如果您从包含以下内容的文件开始:
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my
cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}
]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
... 我假装你的输出的第二行和第三行被分成两行,其中一行在较早的 }
; awk
调用将输出:
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
您可以将其重定向到新文件。
我是 oracle 和 unix 世界的新手,正在为这个问题苦苦挣扎。
我在一个文件中假脱机数据。 sql plus 的行大小限制为 32767,任何返回的大于该限制的数据记录都将换行到下一行。然后将创建的此文件上传到第三方服务,该第三方服务需要 json 格式的数据,仅在末尾有换行符,即在 }
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
如果在假脱机数据时出现自动换行,则在每行之间插入一个 \n
字符,自动换行并中断此 json 数据。
我是否可以在这个假脱机文件中转义控制字符,如 \n
只有当它不在 }
之后出现时?
我可以使用任何 unix 命令吗?
任何帮助将不胜感激
TIA
在不太了解您的设置的情况下,一种选择是通过 sed 脚本传输文件,如下所示:
cat input.txt | sed -e ':start; /^{.*]}$/{p;d}; N;s/\n//g; b start;' > output.txt
这基本上是这样工作的:
- :start 创建一个分支标签跳转到
- /^{.*}$/{p;d} 查找 start/end 带有大括号的行,然后打印它们并移至下一行
- N 这只发生在上一行 NOT 找到匹配项,并读取下一行
- s/\n//g 删除所有换行符(不替换它们),
- b start 分支(跳转)回到起始标签
本质上它所做的是读取一行,检查它是否以大括号开始和结束。如果是,请打印并继续。如果没有,抓住下一行。当然,这假设 oracle 将始终输出以 { 开头并以 } 结尾的行(即大括号前后没有空格)。
模仿 this answer on a sister site,如果你在 Unix 中有你的假脱机文件,你可以将行与 awk
:
awk '{if (sub(/\]}$/,"")) printf "%s]}\n", [=10=]; else printf "%s", [=10=]}' yourfile.lis
如果您从包含以下内容的文件开始:
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my
cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}
]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
... 我假装你的输出的第二行和第三行被分成两行,其中一行在较早的 }
; awk
调用将输出:
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
{"id":"test","brand":"Disney","variants":[{"pid":"cup","name":"my cup"}]}
您可以将其重定向到新文件。