Regex 使用bash脚本将IANA向后文件转换为json文件 什么
我想将转换为具有唯一键的json文件,但为了做到这一点,我必须确保键成为值,反之亦然 这是因为json文件不能有重复的密钥 例子: 该文件包含大量重复链接,但在本例中,让我们使用以下两个:Regex 使用bash脚本将IANA向后文件转换为json文件 什么,regex,bash,shell,sed,Regex,Bash,Shell,Sed,我想将转换为具有唯一键的json文件,但为了做到这一点,我必须确保键成为值,反之亦然 这是因为json文件不能有重复的密钥 例子: 该文件包含大量重复链接,但在本例中,让我们使用以下两个: Link America/Toronto America/Montreal Link America/Toronto Canada/Eastern 我想把它们变成: “美国/蒙特利尔”:“美国/多伦多”, “加拿大/东部”:“美洲/多伦多” 这样他们都能输出多伦多 到目前为止,我
Link America/Toronto America/Montreal
Link America/Toronto Canada/Eastern
我想把它们变成:
“美国/蒙特利尔”:“美国/多伦多”,
“加拿大/东部”:“美洲/多伦多”
这样他们都能输出多伦多
到目前为止,我所尝试的:
到目前为止,我制作的正则表达式是:
- 搜索:
^Link[\s]*([a-zA-Z\/\-]*)[\s]*([a-zA-Z\/\-]*)$
- 替换为:
“\2”:“\1”,
sed-E的链接[\s]*([a-zA-Z\/\-]*)[\s]*([a-zA-Z\/\-]*)$|“\2:“\1”|”。/向后
但出于某种原因,它一直输出整个文件,而不替换任何内容
我做错了什么?我强烈建议使用
jq
,这是一个基于JSON构建的工具(因此,与sed
不同,它无法生成无效的JSON输出,除非明确指向)
以下内容是为了便于阅读而不是简洁:
input='
Link America/Toronto America/Montreal
Link America/Toronto Canada/Eastern
'
# -R == raw input; -n == don't consume input until directed by "input" or "inputs"
jq -Rn '
# start by creating an array of smaller arrays, one per line
[inputs
| select((. | length) > 1) ## ignore empty lines
| split("[[:space:]]+"; "") ## Split on runs of whitespace
| select(.[0] == "Link")] ## Ignore anywhere first column is not "Link"
# then combine those smaller arrays to create key/value pairs in one big object
| reduce .[] as $item ({}; .[$item[2]]=$item[1])
' <<<"$input"
…正如你在
或者,使用Python编写相同的逻辑(包装为从shell调用):
#通过引用的代码在变量中捕获Python代码
#这允许它作为文本包含在shell脚本中
link2json_py=$(cat我强烈建议使用jq
,这是一个基于JSON构建的工具(因此,与sed
不同,除非明确指示,否则无法生成无效JSON的输出)
以下内容是为了便于阅读而不是简洁:
input='
Link America/Toronto America/Montreal
Link America/Toronto Canada/Eastern
'
# -R == raw input; -n == don't consume input until directed by "input" or "inputs"
jq -Rn '
# start by creating an array of smaller arrays, one per line
[inputs
| select((. | length) > 1) ## ignore empty lines
| split("[[:space:]]+"; "") ## Split on runs of whitespace
| select(.[0] == "Link")] ## Ignore anywhere first column is not "Link"
# then combine those smaller arrays to create key/value pairs in one big object
| reduce .[] as $item ({}; .[$item[2]]=$item[1])
' <<<"$input"
…正如你在
或者,使用Python编写相同的逻辑(包装为从shell调用):
#通过引用的代码在变量中捕获Python代码
#这允许它作为文本包含在shell脚本中
link2json_py=$(cat我假设您使用的是GNU sed。您的问题来自GNU扩展正则表达式的特殊性,不幸的是,这些表达式没有很好的文档记录。例如:
速记
类\w
、\w
、\s
和\s
可以用来代替[:alnum:][/code>,
[^[:alnum:]
,[[:space:]
和[^[:space:]
。您可以使用这些
直接在正则表达式中,但不在括号表达式中。反斜杠
括号内的表达式始终是一个文本
因此,您不能在[…]
集合定义中使用\s
的缩写[:space:][/code>。正如所述,您不需要集合定义和:
sed -E 's|^Link\s*([a-zA-Z\/\-]*)\s*([a-zA-Z\/\-]*)$|"\2" : "\1"|' ./backward
应该有效。如果出于任何原因,您希望使用集合定义
sed -E 's|^Link[[:space:]]*([a-zA-Z\/\-]*)[[:space:]]*([a-zA-Z\/\-]*)$|"\2" : "\1"|' ./backward
也应该有效。请注意:
sed -E 's|^Link\s+([a-zA-Z\/\-]+)\s+([a-zA-Z\/\-]+)$|"\2" : "\1"|' ./backward
可能更好。而且:
sed -E 's|^Link\s+([[:alpha:]/-]*)\s+([[:alpha:]/-]*)$|"\2" : "\1"|' ./backward
更好。我假设您使用的是GNU sed。您的问题来自于GNU扩展正则表达式的特殊性,不幸的是,这些表达式没有很好的文档记录。例如:
速记
类\w
、\w
、\s
和\s
可以用来代替[:alnum:][/code>,
[^[:alnum:]
,[[:space:]
和[^[:space:]
。您可以使用这些
直接在正则表达式中,但不在括号表达式中。反斜杠
括号内的表达式始终是一个文本
因此,您不能在[…]
集合定义中使用\s
的缩写[:space:][/code>。正如所述,您不需要集合定义和:
sed -E 's|^Link\s*([a-zA-Z\/\-]*)\s*([a-zA-Z\/\-]*)$|"\2" : "\1"|' ./backward
应该有效。如果出于任何原因,您希望使用集合定义
sed -E 's|^Link[[:space:]]*([a-zA-Z\/\-]*)[[:space:]]*([a-zA-Z\/\-]*)$|"\2" : "\1"|' ./backward
也应该有效。请注意:
sed -E 's|^Link\s+([a-zA-Z\/\-]+)\s+([a-zA-Z\/\-]+)$|"\2" : "\1"|' ./backward
可能更好。而且:
sed -E 's|^Link\s+([[:alpha:]/-]*)\s+([[:alpha:]/-]*)$|"\2" : "\1"|' ./backward
更好。解决方案:
我的问题的答案解决方案是以下命令:
sed-En的|^链接[:space:][]*([^[:space:][]*)[:space:][]*([^[:space:][]*)$|“\2:“\1”| p./向后
它按预期工作,并创建JSON输出的主体
TL/DR:
具体来说,雷诺的回答让我意识到我必须使用[[:space:]
而不是[/s]
在运行他的命令后,我留下了几行不需要的行:
A)文件顶部包含的注释
i、 e#此文件是…
(通过在脚本的开头添加-n
标志和结尾添加p
标志,告诉sed
不要打印不匹配的行(发现不匹配的行),解决了这个问题)
及
B)某些未转换的行
i、 eLink太平洋/Pago_帕果太平洋/Samoa
(这是通过告诉sed
匹配组[^[:space:]
中任何非空格的内容来解决的)
最后,整个脚本:
看起来像这样:
#!/bin/bash
echo "{";
sed -En 's|^Link[[:space:]]*([^[:space:]]*)[[:space:]]*([^[:space:]]*)$| "\2": "\1"|p' ./backward
echo "}";
然后像这样运行脚本:sh index.sh>timezones.json
输出一个漂亮的json文件。解决方案:
我的问题的答案解决方案是以下命令:
sed-En的|^链接[:space:][]*([^[:space:][]*)[:space:][]*([^[:space:][]*)$|“\2:“\1”| p./向后
它按预期工作,并创建JSON输出的主体
TL/DR:
具体来说,雷诺的回答让我意识到我必须使用[[:space:]
而不是[/s]
在运行他的命令后,我留下了几行不需要的行:
A)文件顶部包含的注释
i、 e#此文件是…
(通过在脚本的开头添加-n
标志和结尾添加p
标志,告诉sed
不要打印不匹配的行(发现不匹配的行),解决了这个问题)
和