Usando a linguagem TXR:
@(bind inherit-time nil)
@(bind inherit-sched nil)
@(collect)
@ (all)
@indent/* ---------- @jobname ---------- */
@ (and)
@/ *//* ---------- @nil#@type#@nil ---------- */
@ (end)
@ (bind is-indented @(> (length indent) 0))
@ (gather :vars ((time "") (sched "") (mach "") (descr "") (cmd "")))
@/ */start_times: "@*time"
@/ */days_of_week: @sched
@/ */machine: @mach
@/ */description: "@*descr"
@/ */command: @cmd
@ (until)
@ (end)
@ (cases)
@ (bind type "box")
@ (set (inherit-time inherit-sched) (time sched))
@ (or)
@ (bind type "cmd")
@ (bind is-indented t)
@ (set (time sched) (inherit-time inherit-sched))
@ (end)
@(end)
@(output)
"Job Name", "Time", "Schedule", "Machine", "Description", "Command"
@ (repeat)
"@jobname", "@time", "@sched", "@mach", "@descr", "@cmd"
@ (end)
@(end)
Esta é uma abordagem muito ingênua. De cada registro, extraímos todos os campos nos quais estamos interessados, substituindo espaços em branco por aqueles que não estão presentes (os valores padrão no argumento :vars
de @(gather)
). Nós prestamos atenção ao tipo de trabalho ( box
ou cmd
) e recuo. Quando vemos uma caixa, copiamos algumas propriedades da caixa em variáveis globais; e quando vemos um cmd indentado, ele copia essas propriedades. (Assumimos cegamente que eles foram configurados por umbox
anterior.)
Executar:
$ txr jobs.txr jobs
"Job Name", "Time", "Schedule", "Machine", "Description", "Command"
"TA#box#AbC_p", "16:15", "su", "", "Job AbC that runs at 4:15PM on Sundays, and should end before 5:30PM", ""
"TA#cmd#EfGJob_p", "16:15", "su", "vm_machine1", "job EfG that runs within box AbC", "/path/to/shell/script.sh"
Observe que a saída é campos entre aspas separados por vírgulas, mas nada é feito com relação à possibilidade de que os dados contenham cotações. Se aspas são de alguma forma escapadas em description:
, então isso será preservado, é claro. A notação @*descr
é uma correspondência gulosa e, portanto, description: "a b"c\"d"
resultará em descr
assumindo os caracteres a b"c\"d
, que serão reproduzidos na íntegra na saída.
O interessante dessa solução é que, se não tivermos um exemplo dos dados, podemos adivinhá-los a partir da estrutura do código, já que ele expressa uma correspondência de padrão ordenada no arquivo. Podemos ver que há seções sendo coletadas que começam com uma linha /* --- ... --- */
, na qual um nome de trabalho é incorporado, e que há um campo de tipo entre duas marcas de hash no meio do nome do trabalho. Em seguida, uma linha em branco obrigatória segue após as quais as propriedades são reunidas até outra linha em branco e assim por diante.