使用 sed 解析结果

使用 sed 解析结果

您好,我正在尝试解析 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
}

相关内容