Busybox — это не дистрибутив, на нем нет менеджера пакетов. Он также не имеет разделяемых библиотек по умолчанию (*), поэтому вам нужно статически компоновать все, что в основном означает перекомпиляцию всего, что вы хотите поместить в него.
(*)Возможно, в вашей конкретной производной Busybox есть разделяемые библиотеки, но у вас не будет заголовков для них, поэтому вы также не сможете их использовать.
Это gawk
решение было протестировано на GNU Awk v5.1.0.
Он состоит из сценария Bash, который принимает два входных файла :yaml_template
(, указанных в OP):
$ cat yaml_template
number: {{NUMBER}}
name: {{NAME}}
region: {{REGION}}
storenum: {{STORENUM}}
clients: {{CLIENTS}}
tags: {{TAGS}}
storename: {{STORENAME}}
employee: {{EMPLOYEE}}
products: {{PRODUCTS}}
и data.csv
(, предложенные @cas в его ответе):
$ cat data.csv
NUMBER,NAME,REGION,STORENUM,CLIENTS,TAGS,STORENAME,EMPLOYEE,PRODUCTS
37579922,Store1,New York,32,100,stores,Store newyork,10,200
2,Store2,Somewhere,2,100,"tag1,tag2,tag3",Somewhere Store,5,10
3,Store3,Elsewhere,3,100,"tag1,tag3",Elsewhere Store,3,100
Сценарий Bash, yamlit.sh
делается исполняемым (с помощью cmd$ chmod ug+x yamlit.sh
):
$ cat yamlit.sh
#!/usr/bin/env bash
gawk -F"[,:]" '
FNR==NR {
match($0,/[^[:blank:]]+/); i++;
if (RSTART-1 < 0) {$1="";null++; teenar[i] = ""} else {$1 = substr($1,RSTART); teenar[i] = $1};
teenof[$1] = RSTART - 1;
next;
}
FNR==1 {nteen=i; ncol=split(tolower($0), colhead, ",");next;}
{
for (i=1; i<=nteen; i++) {
offset=teenof[teenar[i]];
if (offset >= 0) {
patsplit($0,datafield,"([^,]*)|(\"[^\"]*\")")
for (j=1; j<=ncol; j++) {
if (tolower(teenar[i]) == colhead[j]) {
printf "%*s: %s\n", length(teenar[i]) + offset, teenar[i], datafield[j];
}
}
}
else {print ""}
}
printf "\n%s\n", "=========================="
}' "$1" "$2"
Скрипт при запуске из терминала дает результат:
$ yamlit.sh yaml_template data.csv
number: 37579922
name: Store1
region: New York
storenum: 32
clients: 100
tags: stores
storename: Store newyork
employee: 10
products: 200
==========================
number: 2
name: Store2
region: Somewhere
storenum: 2
clients: 100
tags: "tag1,tag2,tag3"
storename: Somewhere Store
employee: 5
products: 10
==========================
number: 3
name: Store3
region: Elsewhere
storenum: 3
clients: 100
tags: "tag1,tag3"
storename: Elsewhere Store
employee: 3
products: 100
==========================
Слово пояснения:
$ yamlit.sh yaml_template data.csv >| yaml_out
, data.csv
, Что можно добавить?
Функции, которые было бы тривиально добавить в скрипт, включают:
data.csv
и ключами ввода шаблона yaml в файле шаблона Код:
FNR==NR {...}
вычисляет:teenof
, сокращение от "TEMplate ENTry OFFset". Отрицательные значения указывают на пустую строку в файле шаблона. teenar
, сокращение от «TEMplate ENtry ARray». FNR==1 {...}
помещает каждый заголовок столбца файла data.csv
в третий массив colhead
. {...}
делает несколько вещей:data.csv
запись файла в соответствии с регулярным выражением поля, способным определить, состоит ли какое-либо поле в записи из строки в кавычках, содержащей другие разделители полей (здесь,
)или нет. Компоненты, полученные в результате разделения, помещаются в четвертый массив :datafield
. Критика:
awk
далеко не идеально с вычислительной точки зрения. Сложность O (n^2 ). Однако это сделало возможным обобщение решения с точки зрения файлов data.csv
, имеющих произвольный порядок столбцов относительно порядка записей в файле шаблона yaml. Я не стал тратить время на поиск другого решения. Не уверен, что есть лучше с awk
... teenof
и teenar
), построенные из шаблонов yaml, предположительно с таким количеством записей, как есть столбцы данных. Из этих 4 массивов только один(datafield
)очищается и перестраивается для каждой записи файла data.csv
. Остальные статичны. Тем не менее, я не уверен, что сжатие массива Gawk новым перераспределяет память так же эффективно, как C для удаленной/переобъявленной переменной массива. Я оставляю это для других, более осведомленных, чем я, чтобы прокомментировать. ХТН.