2016-04-30 5 views
1

Вот пример файла, который я хочу преобразовать в json.Преобразование форматированного файла в json с awk (обработка непустых строк)

Name: Jack 
Address: Fancy road and some special characters :"'[email protected]|, 
    City 
    Country 
ID: 1 

Специальные символы - это двойная кавычка, одинарная кавычка, $, @, pipe. Я думал, что я могу использовать разделитель записей в awk:

awk -F ":" '{RS="\n"}{print $1}' 

Однако то, что я получаю:

Name: 
Address 
    City 
    Country 
ID 

Я экспериментировал с изменением записи разделитель «^ [A-Za-z0-9 ] ", чтобы попытаться поймать строки, которые не начинаются с пробела, но почему-то это не работает. Другая попытка состоит в том, чтобы просто проанализировать файл по строкам и форматировать выходное условие для содержимого каждой строки, но это медленно.

В идеале я хотел бы преобразовать файл:

{ 
"Name": "Jack", 
"Address": "Fancy road and some special characters :\"'[email protected]|, City, Country", 
"ID": "1" 
} 
+0

@ hek2mgl: да, извините, исправляя его сейчас. : \ – econ

ответ

2

ИДК почему ваш вопрос говорит о непустых строк, когда нет пустых строк в вашем примере, но с GNU AWK для третьего Arg, чтобы соответствовать () и gensub():

$ cat tst.awk 
BEGIN { printf "{" } 

match($0,/^(\S[^:]+):\s*(.*)/,a) { 
    prt() 
    key = a[1] 
    val = a[2] 
    next 
} 

{ val = gensub(/,\s*$/,"",1,val) gensub(/^\s*/,", ",1) } 

END { prt(); print "\n}" } 

function prt() { 
    if (key != "") { 
     printf "%s\n\"%s\": \"%s\"", (++c>1?",":""), key, gensub(/"/,"\\\\&","g",val) 
    } 
} 

$ awk -f tst.awk file 
{ 
"Name": "Jack", 
"Address": "Fancy road and some special characters :\"'[email protected]|, City, Country", 
"ID": "1" 
} 

Некоторые дополнительные комментарии по коду:

match()

Функция соответствия выполняет поиск строки, строки, для самой длинной, самой левой подстроки, соответствующей регулярному выражению, regexp. Он возвращает позицию символа или индекс, где начинается эта подстрока (1, если она начинается в начале строки).

\S

Соответствует любому символу, который не пробельные. Подумайте об этом как сокращении для «[^ [: space:]]».

\s

Соответствует любой символ пробела. Подумайте об этом как сокращении для «[[: space:]]».

+0

@ hek2mgl: извините, я думаю, что это мое плохое. – econ

+1

Большое спасибо! Я изменил '/ [" \ 047 $ @ |]/'на'/["] /', так как это была моя ошибка, чтобы избежать двойных кавычек, и она отлично работает! :) – econ

+0

Добро пожаловать. Вам не нужно указывать '' 'в выражении скобки, это просто буквальный символ. Я обновил свой ответ, чтобы отразить ваш обновленный желаемый результат. –