我想将 a 的整个条目转换cat /proc/cpuinfo
为 的 JSON "key" : "value"
。
这可能吗?我尝试使用分解字符串,\n
希望能够得到每一行,然后我可以使用分解每一行:
。
但换行符似乎会产生不一致的数组。
答案1
好吧,对于一个简单的方法,你可以这样做:
sed 's/\(.*\)\t:\(.*\)/"\1" : "\2"/' /proc/cpuinfo
这将匹配制表符前的所有内容,后跟冒号并将其保存为\1
,然后是冒号后面的所有内容并将其保存为\2
。替代品在它们周围加上引号。
然而,这会导致以下情况:
"fpu " : " yes"
power management:
制表符前有额外空格的项目将包含其空格,而空的将被忽略。此 Perl 版本可以正确处理这些问题:
perl -F: -alpe 's/.*/"$F[0]" : "$F[1]"/' /proc/cpuinfo
这会将行拆分:
为@F
数组(-F
设置要拆分的字符并-a
打开自动拆分为@F
)并打印引用的每一侧。如果:
一行上有多于一个,它就会中断,但我认为这种情况永远不会发生在/proc/cpuinfo
.但是,它还会打印文件中的所有空白行。为了避免这种情况,请先通过管道grep
:
grep . /proc/cpuinfo | perl -F: -alpe 's/.*/"$F[0]" : "$F[1]"/' /proc/cpuinfo
或者,仅在一行包含以下内容时打印:
:
perl -F: -alne 's/.*:.*/"$F[0]" : "$F[1]"/ && print' /proc/cpuinfo
答案2
sed -n '/./s/ *\(\( *[^:[:blank:]]\)*\)[^:]*\(:*\)/"\1"\3/gp' /proc/cpuinfo
...工作于sed
.使用 GNU 快捷方式,您可以编写几乎相同的语句,例如:
sed -En 's/ *(( ?[^ :\t])+)\s*(:?)/"\1"\3/gp' /proc/cpuinfo
这有点蹩脚(因为我可以通过几次按键做得更好jw
),但我正在玩sed
……
set ' ' $'\\\n' $'\n' ' '
sed -En "\$c$2$1}$2]${3}1ccpus$1=$1[$2$1{$3/^$/c$2$1},$2$1{
s/ *(( ?[^ :\t])+)(\s*:\s*)?\s*/\"\1\"\3/g
s/\"(([yn]).s?|([0-9]+))\"$/\3false\2true/
s/falsey|ntrue|([0-9])f\w+$/\1/
/^.flags./{
s/\s*:\s*/$1=$1[/;h
s/.*\t.//;x;s/(.*\t.).*/\1/;x
s/ /\",$2\"/g
s/^/pr -to24 -a4 <<''$2/e;H;x
s/$/$2$1$1]/
}; s/.*/$1$4&,/p" /proc/cpuinfo
我思考输出接近有效。我拍了一张照片,因为我似乎永远无法像在终端窗口中那样在浏览器窗口中排列选项卡。
无论如何,大多数表格都被骗了——pr
是吗?旗帜通过 GNUsed
e
命令重新格式化,其余的我尽可能保留原始格式化的输出。例如,因为我必须在名称成员周围插入两个字符(双引号),所以当我还插入前导制表符时,我将其设置为 1 个实际制表符,后跟 6 个空格,粗略地尝试保留当前制表符停止位置。
这是第一个哈希值:
答案3
我的版本:
#!/usr/bin/env perl
use strict;
use warnings;
use JSON;
use Storable qw(dclone);
my ( %h, @cpu );
while (<>) {
chomp;
if (m/^$/o) {
push @cpu, dclone( \%h );
undef %h;
next;
}
my ( $k, $v ) = split /\s*:\s*/, $_, 2;
if ( !defined $v or $v eq '' ) { $h{$k} = undef }
elsif ( $k eq 'flags' ) { $h{$k} = [ split /\s/, $v ] }
elsif ( $v =~ /^\d+$/o ) { $h{$k} = int ($v) }
elsif ( $v eq 'yes' ) { $h{$k} = \1 }
elsif ( $v eq 'no' ) { $h{$k} = \0 }
else { $h{$k} = $v }
}
print JSON->new->pretty->encode( \@cpu );
这假设每个 CPU 定义之间有一个空行。