您好,我正在尝试解析 du 命令的结果,但我不知道如何在不循环的情况下执行此操作,我执行以下命令
du -shm /var/vmail/mailboxes/domain/*/mail
我的结果是一个列表,例如:
80 /var/vmail/mailboxes/domain/USER1/mail
150 /var/vmail/mailboxes/domain/USER2/mail
220 /var/vmail/mailboxes/domain/USER3/mail
我想将上面的列表转换为 json 对象,如下所示:
{USER1: 80, USER2:150, USER3:220 }
或者至少拥有一些东西:
80 USER1
150 USER2
220 USER3
我尝试过sed -e
但没有成功,有什么想法吗?
答案1
尝试
du -sm /var/vmail/mailboxes/domain/*/mail |
sed 's:/var/vmail/mailboxes/domain/::; s:/mail::'
在哪里
s:/mail::
将/mail
被什么都取代
转到 json
du -sm /var/vmail/mailboxes/domain/*/mail |
sed 's:/var/vmail/mailboxes/domain/::; s:/mail::' |
awk 'BEGIN { sep="{" ;} { printf "%s \"%s\":%s",sep,$2,$1; sep="," } END { printf "}\n"}'
答案2
du -shm /var/vmail/mailboxes/domain/*/mail | awk -F '[ /]' '{ print $1, $7 }'
du
使用您给出的格式的输入,这将产生
80 USER1
150 USER2
220 USER3
该awk
程序只是从 的输出中挑选出适当的字段du
。它将每一行解释为由空格或斜杠分隔的字段。
awk -F '[ /]' '{ print $1, $(NF - 1) }'
也会起作用。
要将其转换为 JSON,请使用jq
:
du -shm /var/vmail/mailboxes/domain/*/mail |
awk -F '[ /]' '{ print $1, $7 }' |
jq -sR 'split("\n")[0:-1] | map(split(" ")) | map({(.[1]):.[0]}) | add'
这会产生
{
"USER1": "80",
"USER2": "150",
"USER3": "220"
}
该jq
表达式首先将输入拆分为单独的数组元素(每行输入一个),然后再次将这些元素按空格拆分为子数组。此时我们有
[
[
"80",
"USER1"
],
[
"150",
"USER2"
],
[
"220",
"USER3"
]
]
之后,创建对象,其中每个子数组中的第二个元素作为键,第一个元素作为值:
[
{
"USER1": "80"
},
{
"USER2": "150"
},
{
"USER3": "220"
}
]
最后add
给了我们最终的结果。
答案3
您可以使用awk
转换为 2 列格式:
$ du -shm | awk -F/ '{print $1" "$(NF - 1)}'
80 USER1
150 USER2
220 USER3
对于 JSON,请尝试:
$ du -shm | awk -F/ '{print "\""$(NF - 1)"\":"$1}' | paste -sd, | printf "{$(cat)}" | jq
{
"USER1": 80,
"USER2": 150,
"USER3": 220
}
答案4
这有点棘手sed
。不过,这里有一个适用于 GNU sed 的带注释的建议:
解析.sed
s|([^ ]+) .*/([^/]+)/.*| "\2" : \1,| # Extract size and name in json-format
1h; 1!H # Correctly add them to hold-space
$ {
z # Clear pattern-space
s/^/\{/ # Prepend start-curly-brace
G # Fetch formatted json from hold-space
s/,$// # Remove last comma
s/$/\n\}/ # Append end-curly-brace
p # Print
}
像这样运行它:
du -shm /var/vmail/mailboxes/domain/*/mail | sed -Enf parse.sed
或者作为一句单行:
du -shm /var/vmail/mailboxes/domain/*/mail |
sed -Ene 's|([^ ]+) .*/([^/]+)/.*| "\2" : \1,|;1h;1!H;${z;s/^/\{/;G;s/,$//;s/$/\n\}/;p}'
两种情况下的输出:
{
"USER1" : 80,
"USER2" : 150,
"USER3" : 220
}