Это вопрос о том, как преобразовать «непарсируемый» вывод в json или что-то легко потребляемое как json. Это "немного" немного позади тривиальных вещей, поэтому я хотел бы знать, как вы решаете эти вещи в принципе, речь идет не только об этом конкретном примере c. Но пример:
У нас есть эта команда, которая показывает данные об аудиовходах:
pacmd list-sink-inputs
она печатает что-то вроде этого:
2 sink input(s) available.
index: 144
driver: <protocol-native.c>
flags:
state: RUNNING
sink: 4 <alsa_output.pci-0000_05_00.0.analog-stereo>
volume: front-left: 15728 / 24% / -37.19 dB, front-right: 15728 / 24% / -37.19 dB
balance 0.00
muted: no
current latency: 70.48 ms
requested latency: 210.00 ms
sample spec: float32le 2ch 44100Hz
channel map: front-left,front-right
Stereo
resample method: copy
module: 13
client: 245 <MPlayer>
properties:
media.name = "UNREAL! Tetris Theme on Violin and Guitar-TnDIRr9C83w.webm"
application.name = "MPlayer"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "32"
application.process.id = "1543"
application.process.user = "mmucha"
application.process.host = "vbDesktop"
application.process.binary = "mplayer"
application.language = "C"
window.x11.display = ":0"
application.process.machine_id = "720184179caa46f0a3ce25156642f7a0"
application.process.session_id = "2"
module-stream-restore.id = "sink-input-by-application-name:MPlayer"
index: 145
driver: <protocol-native.c>
flags:
state: RUNNING
sink: 4 <alsa_output.pci-0000_05_00.0.analog-stereo>
volume: front-left: 24903 / 38% / -25.21 dB, front-right: 24903 / 38% / -25.21 dB
balance 0.00
muted: no
current latency: 70.50 ms
requested latency: 210.00 ms
sample spec: float32le 2ch 48000Hz
channel map: front-left,front-right
Stereo
resample method: speex-float-1
module: 13
client: 251 <MPlayer>
properties:
media.name = "Trombone Shorty At Age 13 - 2nd Line-k9YUi3UhEPQ.webm"
application.name = "MPlayer"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "32"
application.process.id = "2831"
application.process.user = "mmucha"
application.process.host = "vbDesktop"
application.process.binary = "mplayer"
application.language = "C"
window.x11.display = ":0"
application.process.machine_id = "720184179caa46f0a3ce25156642f7a0"
application.process.session_id = "2"
module-stream-restore.id = "sink-input-by-application-name:MPlayer"
очень приятно. Но мы не хотим показывать пользователю все это, мы просто хотим показать индекс (id ввода), application.process.id, application.name и media.name в некотором приемлемом формате. Было бы здорово разобрать его как-то до json, но даже если я каким-то образом предварительно обработаю его, jq
выходит далеко за пределы моих возможностей и довольно сложен. Я пробовал несколько подходов, используя jq, с регулярным выражением или без него, но я не смог его завершить. И я думаю, мы не можем полагаться на порядок или наличие всех полей.
Мне удалось выполнить работу, но она неопрятна, неэффективна и, следовательно, не требует запятой в имени носителя или имени приложения. Не приемлемое решение, но это единственное, что мне удалось довести до «конца».
Неправильное решение:
cat exampleOf2Inputs |
grep -e "index: \|application.process.id = \|application.name = \|media.name = " |
sed "s/^[ \t]*//;s/^\([^=]*\) = /\1: /" |
tr "\n" ";" |
sed "s/$/\n/;s/index:/\nindex:/g" |
tail -n +2 |
while read A; do
index=$(echo $A|sed "s/^index: \([0-9]*\).*/\1/");
pid=$(echo $A|sed 's/^.*application\.process\.id: \"\([0-9]*\)\".*$/\1/');
appname=$(echo $A|sed 's/^.*application\.name: \"\([^;]*\)\".*$/\1/');
medianame=$(echo $A|sed 's/^.*media\.name: \"\([^;]*\)\".*$/\"\1\"/');
echo "pid=$pid index=$index appname=$appname medianame=$medianame";
done
~ Я вырезал интересующую часть, заменил символы новой строки точкой с запятой , разделить на несколько строк и просто извлечь данные несколько раз с помощью sed. Сумасшедший.
Здесь вывод:
pid=1543 index=144 appname=MPlayer medianame="UNREAL! Tetris Theme on Violin and Guitar-TnDIRr9C83w.webm"
pid=2831 index=145 appname=MPlayer medianame="Trombone Shorty At Age 13 - 2nd Line-k9YUi3UhEPQ.webm"
, который легко конвертируется в любой формат, но вопрос был о json, поэтому:
[
{
"pid": 1543,
"index": 144,
"appname": "MPlayer",
"medianame": "UNREAL! Tetris Theme on Violin and Guitar-TnDIRr9C83w.webm"
},
{
"pid": 2831,
"index": 145,
"appname": "MPlayer",
"medianame": "Trombone Shorty At Age 13 - 2nd Line-k9YUi3UhEPQ.webm"
}
]
Теперь я хотел бы посмотреть, пожалуйста, как все это делается правильно.