gpt4 book ai didi

json - getent passwd 以正确格式输出为 json

转载 作者:太空宇宙 更新时间:2023-11-04 10:03:33 27 4
gpt4 key购买 nike

我正在使用 jq 来尝试将 bash 命令输出转换为 json。但是,转换失败了。

使用这一行:

hostname && getent passwd | egrep -v '/s?bin/(nologin|shutdown|sync|halt)' | cut -d: -f1 | sudo xargs -I % sh -c  'echo %; chage -l %; echo' | jq --raw-input . | jq --slurp .
  • 主机名必须是 json 的根元素
  • 用户名必须是第一个元素
  • getent passwd输出必须是username的子元素

是这样的: JSON

不使用 jq 的上述命令的输出结果为: Command Output

有人试过将 bash 输出正确地转换为 json 吗?谢谢

最佳答案

I'm using jq...

我知道 jq 在这里很流行,但我要推荐 Xidel为了这个任务。
虽然主要是一个 HTML/XML/JSON 解析器(使用 CSS、XPath、XQuery、JSONiq 和模式模板),但 Xidel 也可以处理基本文本。

你说你想要一个像这样的 json:

{
"hostname": "example",
"users": [
{
"username": "example1",
"details": {
"LastPasswordChange": "Nov 12, 2018",
"PasswordExpires": "never",
"PasswordInactive": "never",
"AccountExpires": "never",
"MinDaysBetweenPasswordChange": "0",
"MaxDaysBetweenPasswordChange": "99999",
"NumOfDaysOfWarningBeforePasswordExpires": "7"
}
},
{
"username": "example2",
"details": {
"LastPasswordChange": "Nov 13, 2018",
"PasswordExpires": "never",
"PasswordInactive": "never",
"AccountExpires": "never",
"MinDaysBetweenPasswordChange": "0",
"MaxDaysBetweenPasswordChange": "99999",
"NumOfDaysOfWarningBeforePasswordExpires": "7"
}
}
]
}

这意味着 users 数组需要为每个用户分别填充对象(根据此 chage 程序的输出创建)。这就是为什么我会选择另一种方法。

假设getent passwd | egrep -v '/s?bin/(nologin|shutdown|sync|halt)' | cut -d: -f1 返回:

root
user1
user2

我们将通过管道传输到 Xidel 以首先创建一个基本的 json:

getent passwd | egrep -v '/s?bin/(nologin|shutdown|sync|halt)' | cut -d: -f1 | xidel -s - --xquery '
{
"hostname":"'$(hostname)'",
"users":x:lines($raw) ! {
"username":.
}
}
'
  • 不需要在原始命令前加上 hostname &&,因为您只需从 Xidel 中调用它(这也使查询更容易)。
  • 使用 x:lines($raw),您可以从 Xidel 的输入(在本例中为标准输入)创建一个包含每一行的序列。要使用的替代函数是 tokenize($raw,"\n")

查询输出:

{
"hostname": "user",
"users": [
{
"username": "root"
},
{
"username": "user1"
},
{
"username": "user2"
}
]
}

接下来我们将从 Xidel 中调用 chage 来创建 details 对象:

getent passwd | egrep -v '/s?bin/(nologin|shutdown|sync|halt)' | cut -d: -f1 | xidel -s - --xquery '
{
"hostname":"'$(hostname)'",
"users":x:lines($raw) ! {
"username":.,
"details":{|
for $x in x:lines(
system(x"chage -l {.}")
)
let $a:=tokenize(
$x,
":"
)
return {
normalize-space($a[1]):normalize-space($a[2])
}
|}
}
}
'
  • system(x"chage -l {.}") 返回 chage -l rootchage -l user1chage -l user2.
  • 使用 x:lines() 围绕它,您再次创建了每个新行的序列。例如,user2 输出的第一行:
Last password change                                  : Oct 23, 2018
  • 对于这个序列(或行)中的每个项目,变量 $a 被创建,它保存这个项目一分为二的序列,以 : 作为分隔符. $a 因此对于第一项:
Last password change                                  # white-space up untill this point! 
Oct 23, 2018
  • 最后,属性值对被创建,空白标准化:
{
"Last password change": "Oct 23, 2018"
}

查询输出:

{
"hostname": "user",
"users": [
{
"username": "root",
"details": {
"Last password change": "never",
"Password expires": "never",
"Password inactive": "never",
"Account expires": "never",
"Minimum number of days between password change": "0",
"Maximum number of days between password change": "99999",
"Number of days of warning before password expires": "7"
}
},
{
"username": "user1",
"details": {
"Last password change": "never",
"Password expires": "never",
"Password inactive": "never",
"Account expires": "never",
"Minimum number of days between password change": "0",
"Maximum number of days between password change": "99999",
"Number of days of warning before password expires": "7"
}
},
{
"username": "user2",
"details": {
"Last password change": "Oct 23, 2018",
"Password expires": "never",
"Password inactive": "never",
"Account expires": "never",
"Minimum number of days between password change": "0",
"Maximum number of days between password change": "99999",
"Number of days of warning before password expires": "7"
}
}
]
}

您可以更进一步:

getent passwd | egrep -v '/s?bin/(nologin|shutdown|sync|halt)' | cut -d: -f1 | xidel -s - --xquery '
{
"hostname":"'$(hostname)'",
"users":x:lines($raw) ! {
"username":.,
"details":{|
for $x in x:lines(
system(x"chage -l {.}")
)
let $a:=tokenize(
$x,
":"
)
return {
string-join(
for $x in tokenize(
normalize-space($a[1]),
" "
)
return
upper-case(
substring(
$x,
1,
1
)
)||substring(
$x,
2
)
):normalize-space($a[2]) ! (
if (. castable as decimal) then
number(.)
else
.
)
}
|}
}
}
'
  • 代替Last password change,使用...
string-join(for $x in tokenize(normalize-space($a[1])," ") return upper-case(substring($x,1,1))||substring($x,2))

...它返回:LastPasswordChange

  • 代替 "99999"(一个字符串),用...
normalize-space($a[2]) ! (if (. castable as decimal) then number(.) else .)

...它返回:99999 作为 xs:decimal 原子类型。

查询输出:

{
"hostname": "user",
"users": [
{
"username": "root",
"details": {
"LastPasswordChange": "never",
"PasswordExpires": "never",
"PasswordInactive": "never",
"AccountExpires": "never",
"MinimumNumberOfDaysBetweenPasswordChange": 0,
"MaximumNumberOfDaysBetweenPasswordChange": 99999,
"NumberOfDaysOfWarningBeforePasswordExpires": 7
}
},
{
"username": "user1",
"details": {
"LastPasswordChange": "never",
"PasswordExpires": "never",
"PasswordInactive": "never",
"AccountExpires": "never",
"MinimumNumberOfDaysBetweenPasswordChange": 0,
"MaximumNumberOfDaysBetweenPasswordChange": 99999,
"NumberOfDaysOfWarningBeforePasswordExpires": 7
}
},
{
"username": "user2",
"details": {
"LastPasswordChange": "Oct 23, 2018",
"PasswordExpires": "never",
"PasswordInactive": "never",
"AccountExpires": "never",
"MinimumNumberOfDaysBetweenPasswordChange": 0,
"MaximumNumberOfDaysBetweenPasswordChange": 99999,
"NumberOfDaysOfWarningBeforePasswordExpires": 7
}
}
]
}

“美化”查询更容易阅读,但如果您更喜欢“缩小”版本:

getent passwd | egrep -v '/s?bin/(nologin|shutdown|sync|halt)' | cut -d: -f1 | xidel -s - --xquery '{"hostname":"'$(hostname)'","users":x:lines($raw) ! {"username":.,"details":{|for $x in x:lines(system(x"chage -l {.}")) let $a:=tokenize($x,":") return {string-join(for $x in tokenize(normalize-space($a[1])," ") return upper-case(substring($x,1,1))||substring($x,2)):normalize-space($a[2]) ! (if (. castable as decimal) then number(.) else .)}|}}}'

关于json - getent passwd 以正确格式输出为 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54254819/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com