Bash for manipulating curly bracket delimited config files [closed] - regex

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Currently I have a config file of the following form:
under Time {
TimeStep = 0.001;
MaxTime = 0.2;
MaxIts = 400;
Type = Implicit;
under Implicit {
Type = ForwardEuler;
Jacobian = FiniteDifference;
under Newton {
MaxIts = 20;
Eps = 0.01;
}
}
}
First Question: I want to write a set of bash scripts that can
set property = value in a file; add it if it is not there.
get property from such a file.
line-by-line editting is not suitable here: take MaxIts for example, the script needs to distinguish between Time.MaxIts and Time.Implicit.MaxIts.
Second Question: I want to write a bash script that transforms above into:
Time.TimeStep = 0.001;
Time.MaxTime = 0.2;
Time.MaxIts = 400;
Time.Type = Implicit;
Time.Implicit.Type = ForwardEuler;
Time.Implicit.Jacobian = FiniteDifference;
Time.Implicit.Newton.MaxIts = 20;
Time.Implicit.Newton.Eps = 0.01;
so that sed or awk can do the job simply.

Here's how to do the 2nd part:
$ cat tst.awk
function descend(name) {
while ( (getline > 0) && !/}/ ) {
if ( /{/ ) {
descend(name "." $2)
}
else {
sub(/^[[:space:]]+/,"")
print name "." $0
}
}
}
{ descend($2) }
$ awk -f tst.awk file
Time.TimeStep = 0.001;
Time.MaxTime = 0.2;
Time.MaxIts = 400;
Time.Type = Implicit;
Time.Implicit.Type = ForwardEuler;
Time.Implicit.Jacobian = FiniteDifference;
Time.Implicit.Newton.MaxIts = 20;
Time.Implicit.Newton.Eps = 0.01;
I'm sure you can write a script to do the reverse mapping and then you can just do all the manipulation related to your first question on the flat format above.

Related

loop failing when wrapped in try catch to run few times [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 10 months ago.
Improve this question
Have this code where i am trying to run a loop for few times to make sure i do get my result, but for some reason, i am still getting an error displayed on sreen and it is not even doing the cflog so i can know what is going on, any help will be appreciated
var aData = [];
for (i = 1; i <= 10; i++) {
try {
var a = {};
var as = calltoapitoogetdata;
a['count'] = as;
ArrayAppend(aData, mData);
var retJSON = serializeJSON(aData);
writedump(retJSON);
//return serializeJSON(aData);
break;
} catch (any e) {
i = i + 1;
cflog(text = "Call failed #i#", application = true, file = "loogevent");
writedump(i);
}
}
Thanks
If your code is still erroring it is most likely coming from the cflog call being made in your cfcatch. If you are running a version of Adobe ColdFusion the script version would be :
WriteLog(type="Error", file="myapp.log", text="[#ex.type#] #ex.message#");
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-t-z/writelog.html
Lucee has made many of the CFScript functions equivalent of their tag names but with Adobe CF there are a number of functions that do not comply with this. <cfdump> -> writeDump for example.
Too long for a comment.
I think troubleshooting is easier if all available information is right in front of you on the screen. So, I would troubleshoot like this. Your code is below with my additions in uppercase:
var aData = [];
for (i = 1; i <= 10; i++) {
try {
WRITEOUTPUT('TRY NUMBER #I# <BR>);
var a = {};
var as = calltoapitoogetdata;
WRITEDUMP(AS);
a['count'] = as;
ArrayAppend(aData, mData);
var retJSON = serializeJSON(aData);
writedump(retJSON);
//return serializeJSON(aData);
break;
} catch (any e) {
i = i + 1; // THIS LINE IS NOT NECESSARY
WRITEOUTPUT('CATCH NUMBER #I# <BR>);
cflog(text = "Call failed #i#", application = true, file = "loogevent"); //THIS LINE GETS REPLACED BY
WRITEDUMP(E);
writedump(i); // THIS LINE GOES AWAY
}
}

Extract hex codes using regex [duplicate]

This question already has answers here:
How can I obfuscate my Perl script to make it difficult to reverse engineer?
(6 answers)
Closed 5 years ago.
I have a file with hex codes. Example:
my $O1ol1ooI = "";
my $lOI100 = "";
my $oO10OI0 = 99;
my #olIIO1 = `df -h`;
chomp(my $I0110 = `hostname`);
foreach (#olIIO1) {
if (m/(\d+)% (.*)/ && $1 > $oO10OI0) {
$lOI100 = "\x66\x75\x6C\x6C";
}
}
my $O1ol1ooI = "";
my $lOI100 = "";
my $oO10OI0 = 99;
my #olIIO1 = `df -ih`;
chomp(my $I0110 = `hostname`);
foreach (#olIIO1) {
if (m/(\d+)% (.*)/ && $1 > $oO10OI0) {
$lOI100 = "\x66\x75\x6C\x6C";
}
}
if ($ol0IOoO eq "\x2D\x2D\x64\x65\x62\x75\x67\x3D\x6F\x6E") {
$OloOlOlII->show_progress;
}
What i need is a regex to be able to extract the hex codes from this file like \x66\x75\x6C\x6C, \x66\x75\x6C\x6C and etc.
Note: The file is so much longer.
Thanks in advance
A regular expression to match a hex code like that is straightforward:
\\x[0-9a-f][0-9a-f]
or
\\x[[:xdigit:]]{2}
Is that enough to solve your problem?

Select only inline code blocks [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I need to select every inline code blocks (not multilane)
Here is text https://regex101.com/r/8e7nPL/7
Example of inline blocks that I need to extract: f.call();, yield(), Fiber
this could help you:
function test(text) {
var re = /`([^`\n]+)`/g;
let match;
while(match = re.exec(text)) {
console.log('match', match);
}
}
test(
`
Пример создания файбера и передача ему в качестве аргумента вызываемой функции:
\`\`\`
auto f = new Fiber(&foo);
\`\`\`
\`f.call();\` вызов файбера
\`Fiber.yield();\` метод \`yield()\` класса \`Fiber\` вызывающий преостановку выполнение текущей функции
Пример:
\`\`\`
import std.stdio;
import core.thread;
void main()
{
auto f = new Fiber(&foo);
f.call(); // Prints Hello
f.call(); // Prints World
}
void foo()
{
writeln("Hello");
Fiber.yield();
writeln("World");
}
\`\`\`
Результат:
\`\`\`
> app.exe
Hello
World\`
`
)

Parser JSON ON QT [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Is it possible to use an operator || in json like this :
{
"ven":{
"source":"logicCtrl" ,
"msg":"radio_volume" || "radio-mute", || "radio3",
"type":"int"
}
}
i can after get data by parsing data in C++ side like this :
QFile jsonFile("VenParser.json");
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "problème d'overture du fichier, exit";
}
QByteArray jsonData = jsonFile.readAll();
QJsonParseError *err = new QJsonParseError();
QJsonDocument doc = QJsonDocument::fromJson(jsonData, err);
if (err->error != 0)
qDebug() << err->errorString();
Venparser myparser;
if (doc.isNull())
{
qDebug() << "Document invalide";
}
else if (doc.isObject())
{
//recuperer l'object json
QJsonObject jObject = doc.object();
//convertir l'object json to variantmap
QVariantMap mainMap = jObject.toVariantMap();
// variant map
QVariantMap Map = mainMap["ven"].toMap();
myparser.source = Map["source"].toString();
myparser.msg = Map["msg"].toString();
myparser.type = Map["type"].toString();
header.H file : i define my struct
struct Venparser {
QString source;
QString msg;
QString type;
My problem is that i don't want a list in my "msg" but something like this :
when i call myparser.msg , then it will check just the value i need in msg and return it.
"msg":"radio_volume" || "radio-mute", || "radio3",
Thanks,
Your example with the || token is not a valid JSON. You can read more about its format here. However, if I understand you correctly, you can easily use JSON arrays for your task.
JSON:
{
"ven": {
"source": "logicCtrl",
"msg": ["radio_volume", "radio-mute", "radio3"],
"type": "int"
}
}
C++:
You can access the msg array using the toStringList() method. Also, you can use QVariantList and toList() respectively if you fill your array with data different from strings.
QStringList messages = Map["msg"].toStringList();
Now the messages variable contains "radio_volume", "radio-mute" and "radio3" values so you can extract the required string any way you need using your code.
If you still need to parse your exact example (which is technically not a valid JSON as I said before), you will have to go with writing your own parser, which is a bit wide topic for the answer.

How can I elegantly handle state when parsing line oriented files using regex?

I have a perl script that I use to extract data from a raw data/log file. I need help on making the script dynamic. First, let me show you the part of the perl script and raw data file.
Perl script:
if ( /Catalyst tester (\S+)\S+/ )
{
$DETAILS{tester_name} = $1;
}
if ( /(CATALYST_TH\s*1)/ )
{
$FOUND_CAT = 1;
$DETAILS{test_head} = $1;
$TEST_HEAD = $1;
}
if ($FOUND_CAT)
{
if ( /(BACKPLANE\s*A)/ )
{
$FRAME = $TEST_HEAD .' '. $1;
$FOUND_BACKPLANE_A = 1;
}
if ( /(BACKPLANE\s*B)/ )
{
$FRAME = $TEST_HEAD . ' ' . $1;
$FOUND_BACKPLANE_B = 1;
}
}
if ( /END/ )
{
$FOUND_CAT = 0;
$FOUND_BACKPLANE_A = 0;
$FOUND_BACKPLANE_B = 0;
$FOUND_PRECISION_1 = 0;
$FOUND_PRECISION_2 = 0;
$FOUND_UB_SPS = 0;
$FOUND_HSD100_1 = 0;
$FOUND_HSD100_2 = 0;
$FOUND_HSD100_3 = 0;
$FOUND_TSY = 0;
$FOUND_TIME_SUB = 0;
}
if ($FOUND_BACKPLANE_A)
{
if ( /(\d+)\s+(\S+)\s+(\w+)\s+\w+\s+\d*\s+\#\s+\S+\s+(?:\d+\s+){2}((?!.*EMPTY\b).+)$/ )
{
push #{$DETAILS{frame}}, $FRAME;
push #{$DETAILS{slot}}, $1;
push #{$DETAILS{part_no}}, $2;
push #{$DETAILS{serial_no}}, $3;
push #{$DETAILS{board_name}}, $4;
}
}
if ($FOUND_BACKPLANE_B)
{
if ( /(\d+)\s+(\S+)\s+(\w+)\s+\w+\s+\d*\s+\#\s+\S+\s+((?!.*EMPTY\b).+)$/ )
{
push #{$DETAILS{frame}}, $FRAME;
push #{$DETAILS{slot}}, $1;
push #{$DETAILS{part_no}}, $2;
push #{$DETAILS{serial_no}}, $3;
push #{$DETAILS{board_name}}, $4;
}
}
if( /(PRECISION\_AC\s*1)/ )
{
$FOUND_PRECISION_1 = 1;
$FRAME = $1;
}
if ($FOUND_PRECISION_1)
{
if ( /(\d+)\s+(\S+)\s+(\w+)\s+\w+\s+\d*\s+\#\s+\S+\s+((?!.*EMPTY\b).+)/ )
{
push #{$DETAILS{frame}}, $FRAME;
push #{$DETAILS{slot}}, $1;
push #{$DETAILS{part_no}}, $2;
push #{$DETAILS{serial_no}}, $3;
push #{$DETAILS{board_name}}, $4;
}
}
## And the rest of the script follows the same format
In my perl script, my logic is if the line/word/header(as I prefer to call it) is found, assign a variable with a true or 1. Then in another if statement if the variable is 1, search for the data needed using regex and store it in a hash.
Now my main problem is that it is not dynamic. If you noticed I did an if statement for every header and the variable that is used to store a 1 is different for every header; if it's Catalyst tester then the variable would be $FOUND_CAT = 1;.
Somethings to take note of: for the header specifically CATALYST_TH 1, there will always be BACKPLANE A or it could be BACKPLANE B. If there is a BACKPLANE B I would have to write another if statement and push everything into the hash again. It's tedious because other log files may have even up to C or D which I do not know of yet, therefore making my script hard to maintain.
Other headers only need one line like PRECISION_AC 1. Only CATALYST_TH 1 will always have a backplane. This is just to take note in case it affects any answers.
So any help on this? Is there anyway to reduce the number of variables? Or even the number or if statements? I've tried but that way it wouldn't push other data into the hash if it's not true. Suggestions would greatly be appreciated.
P.S. Ignore the comments with one '#' symbol, those are part of the log file. The ones with two '#' symbols, like '##' are the comments I have added in.
Since your parsing has lots of state in it depending on what your program has already seen I would switch from regex to Parse-RecDescent, which can easily handle all that state nicely.
It's a steep learning curve at first though. There's a tutorial on it here, and an older, simpler tutorial here.