我有一个 JSON 格式的文件用户名和密码,我想将其转换为流程。
我已经使用了sed
不同的命令来处理它,但我想知道的是如何将这三个命令合并为一个以备将来使用。
原始格式
{ "user.name1" : "hashed_password",
"user.name2" : "hashed_password" }
期望输出
user.name:hashed_password
这些是我运行的命令,但是我无法使用管道将它们链接在一起,或者简单地将它们连接在一起,从而出现错误sed: -e expression #1, char 8: unknown option to 's'
。
违规命令...
sed -i 's/\"//g/s/\,/\n/g/\s//g' input_file
sed: -e expression #1, char 8: unknown option to `s'
如何将以下命令连接成一个?
命令删除双引号
sed -i 's/\"//g' input_file
用新行替换逗号
sed -i 's/\,/\n/g' input_file
删除空格
sed -i 's/\s//g input_file
答案1
要将多个sed
命令放入单个“脚本",您可以使用多个-e
标志(可移植):
sed -i -e 's/\"//g' -e 's/\,/\n/g' -e 's/\s//g' input_file
或者分号分隔符(并非所有实现都可用):
sed -i 's/\"//g;s/\,/\n/g;s/\s//g' input_file
您还需要添加对大括号的处理 - {}
......
话虽如此,为了正确解析和处理 JSON,你不应该真正使用sed
...也许尝试jq
!
jq -r 'keys[] as $k | "\($k):\(.[$k])"' input_file
输出:
user.name1:hashed_password
user.name2:hashed_password
keys[] as $k
将遍历每个键并将其值存储在$k
- IE:
user.name1
,user.name2
- IE:
"\($k):\(.[$k])"
将形成一个字符串,代入$k
和.[$k]
- 使用
-r
从输出字符串中删除引号(生的模式)
使用sed
处理 JSON 会让您面临各种各样的问题...例如,您将如何处理以下(完全有效的 JSON)输入?
{
"user.name1" :
"hashed_password",
"user.name2" :
"hashed_password"
}
答案2
当您处理 JSON 等标准化输入时,通常最好使用适当的解析器而不是正则表达式。例如,您将正确转换任何转义序列(尽管对于您的特定输入数据,这可能无法实现!)。
不幸的是,coreutils 中没有很好的工具来处理 JSON。Attie 提供 jq
如果您可以自由安装软件包,这是一个不错的选择。
如果你无法安装其他软件包,在 Python 中这并不是特别困难。以这个脚本为例:
import json,sys
for (k, v) in json.load(sys.stdin):
print(k + ":" + v)
可以压缩成一行:
cat inputdata | python -c 'import json,sys;print("\n".join((k + ":" + v) for (k, v) in json.load(sys.stdin).items()))'
答案3
对于您在这些命令中执行的简单字符删除,sed
我建议您使用tr
,其唯一目的是删除、压缩或替换单个字符,包括换行符(sed
基于正则表达式,通常依赖换行符作为缓冲区分隔符,因此使用 sed 修改换行符很棘手)。我认为这个tr
命令可以完成您正在寻找的一切:
cat json_filename | tr -d "{}\" \012\011\015" | tr "," "\012"
第一个tr
命令删除所有花括号、双引号、空格、回车符(八进制 012,ASCII 10)、制表符(八进制 011,ASCII 9)和换行符(八进制 015,ASCII 13)。第二个tr
命令将所有逗号替换为回车符。只要您的 JSON 文件的变量名称和值不包含逗号,这些命令就可以让您避免需要专用的 JSON 解析器。
也就是说,如果您有sed
一组独立工作的命令,那么使用“-f”sed
选项从文件中读取单独的命令可能最容易地完成它们的组合。您只需将 s/.../.../g 字符串放入一个文件中,每个字符串占一行,然后在“-f”选项后指定该文件名。例如,如果sed
您列出的三个命令令人满意,您可以将它们放入一个名为“json.convert.sed”的文件中,该文件仅包含以下内容:
s/\"//g
s/\,/\n/g
s/\s//g
然后您可以sed
使用以下命令文件进行调用:
sed -f json.convert.sed
话虽如此,这些sed
命令对我来说无法完成您想要的任务,而且我不确定您是否可以sed
修改换行符。这是因为sed
基于旧的“ed”行编辑器,设计用于一次编辑单行(它的“脚本”版本),因此每行输入都使用换行符作为分隔符进行“解析”,然后将行(不带换行符)传递给编辑引擎,应用编辑命令,然后输出编辑后的行并带有换行符。然后循环重复。我只能使用sed
来修改换行符,方法是首先使用 将换行符更改为某个不同的字符(否则不会出现在输入中) 。如果您想要做的只是删除换行符,那么tr
使用这种方式是没有意义的,因为会为您完成这项工作。但是,例如,如果您想将换行符转换为带有尾随空格的分号,一种方法是:tr
tr
cat input_file | tr "\012" "%" | sed "s/%/; /g"
(换行符被转换为%tr
,然后sed
将所有%字符转换为“;”字符对。)
答案4
您可以像这样组合它:
sed -i 's/\"//g;s/\,/\n/g;s/\s//g' input_file
您忘记添加删除了{}
。因此,您可能需要:
sed -i 's/\"//g;s/\,/\n/g;s/\s//g;s/{//g;s/}//g' input_file