Захват значений на основе разделителя в файле - PullRequest
0 голосов
/ 30 октября 2018

У меня есть файл с данными ниже.

File.txt:

[{name:dany,class:4,Subjects:5,maths:yes,science:yes,EVS:no},{name:Ane,class:5,Subjects:6,maths:yes,science:yes,EVS:Yes},{name:mike,class:5,Subjects:1,maths:yes,science:no,EVS:no}]

Мне нужен выходной файл как:

output.txt:

Dany,5,Yes
Ane,6,Yes
Mike,1,No

Я работал, как показано ниже: B=`cat file.txt | awk -F '},' '{print $1}'`

echo $B | awk -F , '{print $1 " " $3" " $6'}

отображает вывод name:dany subjects:5 evs:no

Я кодировал взять 1-ю строку, я хочу, чтобы то же самое происходило для всего файла, и мне нужен вывод, как я упоминал в вопросе

Примечание: игнорировать регистр слов. Я обновил ввод. Просьба принять, как разделитель для полей и}, как разделитель для записей

Ответы [ 4 ]

0 голосов
/ 31 октября 2018

Контент, возвращаемый из сервиса, подобен JSON.

Вы можете сделать это JSON с помощью нескольких шагов sed. Как только вы это сделаете, вы можете использовать синтаксический анализатор командной строки JSON, например jq для его анализа.

Метки (текст перед двоеточиями) должны быть в кавычках:

sed -E 's/(\s*[a-zA-Z]+)\s*:/"\1":/g'

Нецифровые значения (текст после двоеточий) также должны быть заключены в кавычки:

sed -E 's/:\s*([a-zA-Z]+)\s*/:"\1"/g'

Соединяя это с вашими входными данными, вы получаете этот конвейер:

echo '[{name:dany,class:4,Subjects:5,maths:yes,science:yes,EVS:no},{name:Ane,class:5,Subjects:6,maths:yes,science:yes,EVS:Yes},{name:mike,class:5,Subjects:1,maths:yes,science:no,EVS:no}]' |
    sed -E 's/(\s*[a-zA-Z]+)\s*:/"\1":/g' |
    sed -E 's/:\s*([a-zA-Z]+)\s*/:"\1"/g'

После этого вы можете получить JSON, который может анализировать такой инструмент, как jq:

[{"name":"dany","class":4,"Subjects":5,"maths":"yes","science":"yes","EVS":"no"},{"name":"Ane","class":5,"Subjects":6,"maths":"yes","science":"yes","EVS":"Yes"},{"name":"mike","class":5,"Subjects":1,"maths":"yes","science":"no","EVS":"no"}]

jq может создать отчет с разделением запятыми, используя это:

jq '.[] | "\(.name),\(.Subjects),\(.evs)"' --raw-output
  • .[] проходит через массив, объект за объектом ([...] - это массив JSON, {...} - это объект JSON)
  • "\(.name)" извлекает поле «имя» из текущего объекта и выводит его
  • | объединяет несколько этапов команд jq (пример: .[] | .name выводит поле имени каждого объекта)
  • | "\(.name),\(.Subjects),\(.evs) выводит строку с полями name, Subjects и evs, разделенными запятыми.

Это приведет к выводу:

dany,5,null
Ane,6,null
mike,1,null

Весь конвейер, который соединяет это:

echo '[{name:dany,class:4,Subjects:5,maths:yes,science:yes,EVS:no},{name:Ane,class:5,Subjects:6,maths:yes,science:yes,EVS:Yes},{name:mike,class:5,Subjects:1,maths:yes,science:no,EVS:no}]' |
    sed -E 's/([a-zA-Z]+):/"\1":/g' |
    sed -E 's/:([a-zA-Z]+)/:"\1"/g' |
    jq '.[] | "\(.name),\(.Subjects),\(.evs)"' --raw-output
0 голосов
/ 30 октября 2018

Вы можете установить RS, FS, ORS и OFS для подтверждения ваших входных и выходных данных. Предполагая, что ваши входные данные согласованы, вы можете использовать что-то вроде этого.

awk 'BEGIN{RS="},{";FS="[:,]";ORS="\n";OFS=",";} 1 {print $2,$4,$10}' data.txt

Но разделители полей в вашем входе сильно различаются. Иногда запятая, иногда нет, иногда пробел после запятой, а иногда пробел перед запятой. Так что, похоже, ваш источник данных не работает.

0 голосов
/ 30 октября 2018
$ awk -v RS='}' -F'[]{: ,]+' -v OFS=',' '$3!=""{print $3, $5, $11}' file
dany,4,yes
Ane,5,yes
mike,5,no
0 голосов
/ 30 октября 2018

Это может сработать для вас (GNU sed):

sed -r 's/name:/\n&/2;s/[^\n]*name:(\w*)[^\n]*subjects:(\w*)[^\n]*evs:(\w*)[^\n]*/\1,\2,\3/I;P;D' file

Разделить строки на записи, затем сопоставить шаблон по именам полей и напечатать обязательные поля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...