I'm trying to check whether an environment variable is empty or unset in my PowerShell script. The script is running in a Docker container, and intended to pull new code if an environment variable is defined:
CMD if (-not ([string]::IsNullOrEmpty(env:UPDATE_FROM_GITHUB))) { \
Write-Host Git pull started; \
PortableGit\bin\git.exe pull; \
}; \
I get a bunch of errors:
web_1 | At line:1 char:110
web_1 | + ... ence = 'SilentlyContinue'; if (-not ([string]::IsNullOrEmpty(env:UPDA ...
web_1 | + ~
web_1 | Missing ')' in method call.
web_1 | At line:1 char:110
web_1 | + ... ue'; if (-not ([string]::IsNullOrEmpty(env:UPDATE_FROM_GITHUB))) { Wr ...
web_1 | + ~~~~~~~~~~~~~~~~~~~~~~
web_1 | Unexpected token 'env:UPDATE_FROM_GITHUB' in expression or statement.
web_1 | At line:1 char:110
web_1 | + ... ence = 'SilentlyContinue'; if (-not ([string]::IsNullOrEmpty(env:UPDA ...
web_1 | + ~
web_1 | Missing closing ')' in expression.
web_1 | At line:1 char:110
web_1 | + ... ue'; if (-not ([string]::IsNullOrEmpty(env:UPDATE_FROM_GITHUB))) { Wr ...
web_1 | + ~~~~~~~~~~~~~~~~~~~~~~
web_1 | Missing closing ')' after expression in 'if' statement.
web_1 | At line:1 char:132
web_1 | + ... e'; if (-not ([string]::IsNullOrEmpty(env:UPDATE_FROM_GITHUB))) { Wri ...
web_1 | + ~
web_1 | Unexpected token ')' in expression or statement.
web_1 | At line:1 char:133
web_1 | + ... '; if (-not ([string]::IsNullOrEmpty(env:UPDATE_FROM_GITHUB))) { Writ ...
web_1 | + ~
web_1 | Unexpected token ')' in expression or statement.
web_1 | At line:1 char:134
web_1 | + ... ; if (-not ([string]::IsNullOrEmpty(env:UPDATE_FROM_GITHUB))) { Write ...
I'm not sure how to begin here. The errors seem redundant, but there isn't a clear starting place. Could it have something to do with how Docker parses commands?
PowerShell variables, including environment variables, must always be referred to with sigil $
Therefore, env:UPDATE_FROM_GITHUB must be $env:UPDATE_FROM_GITHUB
To simply test if an environment variable is defined / has a value, you don't strictly need -not [string]::IsNullOrEmpty(...); instead, you can take advantage of PowerShell's implicit Boolean conversion:
$null or the empty string is considered $False
and any nonempty string $True
To put it all together:
CMD if ($env:UPDATE_FROM_GITHUB) { \
Write-Host Git pull started; \
PortableGit\bin\git.exe pull; \
}; \
Related
Wow, this was a terribly worded query, let me try again.
I'm still learning antlr and trying to understand grammars. I'm using a grammar (not written by me - so I'm trying not to adjust it too much as it's the standard used by many groups, found here).
I'm using it in a Flutter application. When I run it on Linux or Android, it runs without issue. When I try and run it no web, I immediately have issues. The full grammar I'm using is below.
grammar FhirPath;
// Grammar rules [FHIRPath](http://hl7.org/fhirpath/N1) Normative Release
//prog: line (line)*; line: ID ( '(' expr ')') ':' expr '\r'? '\n';
entireExpression: expression EOF;
expression:
term # termExpression
| expression '.' invocation # invocationExpression
| expression '[' expression ']' # indexerExpression
| ('+' | '-') expression # polarityExpression
| expression ('*' | '/' | 'div' | 'mod') expression # multiplicativeExpression
| expression ('+' | '-' | '&') expression # additiveExpression
| expression '|' expression # unionExpression
| expression ('<=' | '<' | '>' | '>=') expression # inequalityExpression
| expression ('is' | 'as') typeSpecifier # typeExpression
| expression ('=' | '~' | '!=' | '!~') expression # equalityExpression
| expression ('in' | 'contains') expression # membershipExpression
| expression 'and' expression # andExpression
| expression ('or' | 'xor') expression # orExpression
| expression 'implies' expression # impliesExpression;
//| (IDENTIFIER)? '=>' expression #lambdaExpression
term:
invocation # invocationTerm
| literal # literalTerm
| externalConstant # externalConstantTerm
| '(' expression ')' # parenthesizedTerm;
literal:
'{' '}' # nullLiteral
| ('true' | 'false') # booleanLiteral
| STRING # stringLiteral
| NUMBER # numberLiteral
| DATE # dateLiteral
| DATETIME # dateTimeLiteral
| TIME # timeLiteral
| quantity # quantityLiteral;
externalConstant: '%' ( identifier | STRING);
invocation: // Terms that can be used after the function/member invocation '.'
identifier # memberInvocation
| function # functionInvocation
| '$this' # thisInvocation
| '$index' # indexInvocation
| '$total' # totalInvocation;
function: identifier '(' paramList? ')';
paramList: expression (',' expression)*;
quantity: NUMBER unit?;
unit:
pluralDateTimePrecision
| dateTimePrecision
| STRING; // UCUM syntax for units of measure
pluralDateTimePrecision:
'years'
| 'months'
| 'weeks'
| 'days'
| 'hours'
| 'minutes'
| 'seconds'
| 'milliseconds';
dateTimePrecision:
'year'
| 'month'
| 'week'
| 'day'
| 'hour'
| 'minute'
| 'second'
| 'millisecond';
typeSpecifier: qualifiedIdentifier;
qualifiedIdentifier: identifier ('.' identifier)*;
identifier:
IDENTIFIER
| DELIMITEDIDENTIFIER
| 'as'
| 'is'
| 'contains'
| 'in'
| 'div';
/****************************************************************
Lexical rules ***************************************************************
*/
/*
NOTE: The goal of these rules in the grammar is to provide a date token to the parser. As such it
is not attempting to validate that the date is a correct date, that task is for the parser or
interpreter.
*/
DATE: '#' DATEFORMAT;
DATETIME:
'#' DATEFORMAT 'T' (TIMEFORMAT TIMEZONEOFFSETFORMAT?)?;
TIME: '#' 'T' TIMEFORMAT;
fragment DATEFORMAT:
[0-9][0-9][0-9][0-9] ('-' [0-9][0-9] ('-' [0-9][0-9])?)?;
fragment TIMEFORMAT:
[0-9][0-9] (':' [0-9][0-9] (':' [0-9][0-9] ('.' [0-9]+)?)?)?;
fragment TIMEZONEOFFSETFORMAT: (
'Z'
| ('+' | '-') [0-9][0-9]':' [0-9][0-9]
);
IDENTIFIER: ([A-Za-z] | '_') ([A-Za-z0-9] | '_')*;
// Added _ to support CQL (FHIR could constrain it out)
DELIMITEDIDENTIFIER: '`' (ESC | ~[\\`])* '`';
STRING: '\'' (ESC | ~['])* '\'';
// Also allows leading zeroes now (just like CQL and XSD)
NUMBER: [0-9]+ ('.' [0-9]+)?;
// Pipe whitespace to the HIDDEN channel to support retrieving source text through the parser.
WS: [ \r\n\t]+ -> channel(HIDDEN);
COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN);
fragment ESC:
'\\' ([`'\\/fnrt] | UNICODE); // allow \`, \', \\, \/, \f, etc. and \uXXX
fragment UNICODE: 'u' HEX HEX HEX HEX;
fragment HEX: [0-9a-fA-F];
I generate the code with the following:
antlr4 -Dlanguage=Dart FhirPath.g4 -visitor -no-listener
Then to test I use the following code:
final input = InputStream.fromString('name');
final lexer = FhirPathLexer(input);
final tokens = CommonTokenStream(lexer);
final parser = FhirPathParser(tokens);
parser.buildParseTree = true;
final tree = parser.expression();
If I run it in a simple dart script, it runs without issue. But if I put it in a Flutter application (again, only on web, otherwise it appears to run without issue), I get this error:
line 1:0 mismatched input 'name' expecting {'as', 'in', 'is', 'contains', 'div', 'mod', IDENTIFIER, DELIMITEDIDENTIFIER}
I assume there's something I don't understand about the grammar, so any insights would be appreciated.
I've concluded this is an error with transpiling to javascript. The antlr4 version works for all of my tests for Android and Linux, then throws a bunch of errors for web. I've gone back to using petitparser instead of antlr4. If anyone else has suggestions feel free to leave them, but for now, I'm going to close this. If you want to compare how the two look, I have both versions here: https://github.com/MayJuun/fhir/tree/main/fhir_path/lib
My sample log looks like :
2022-09-01 23:13:05Z | error | 2022-09-02 02:13:05 - [Task] Id:120 Name:OPT_VIM_1HEAD Exception with index:18 | 18.9251137 | Exception:
ERROR connection to partner '10.19.101.17:3300' broken
2022-09-01 23:13:25Z | error | 2022-09-02 02:13:25 - [Task] Id:121 Name:OPT_VIM_1ITEM
ERROR connection to partner '10.19.101.22:3300' broken
2022-09-01 23:13:25Z | error | 2022-09-02 02:13:25 - [Task] Id:121 Name:OPT_VIM_1ITEM RunId:7 Task execution failed with error: One or more errors occurred., detail:
ERROR connection to partner '10.19.101.22:3300' broken
I want to extract the job name OPT_VIM_1HEAD or OPT_VIM_1ITEM (its dynamic) and also the timestamp after the "error" pattern : 2022-09-02 02:13:25 or 2022-09-02 02:13:05 in different variables.
I have also written the script as :
$dir = 'C:\ProgramData\AecorsoftDataIntegrator\logs\'
$StartTime = get-date
$fileList = (Get-ChildItem -Path $dir -Filter '2022-09-02.log' | Sort-Object LastWriteTime -Descending | Select-Object -First 1).fullname
$message = Get-Content $fileList | Where-Object {$_ -like ‘*error*’}
$message
$details = Select-String -LiteralPath $fileList -Pattern 'error' -Context 0,14 | Select-Object -First 1 | Select-Object Path, FileName, Pattern, Linenumber
$details[0]
But not able to retrieve the tokens mentioned above
Use regex processing via the -match operator to extract the tokens of interest from each line:
# Sample lines from the log file.
$logLines = #'
2022-09-01 23:13:05Z | error | 2022-09-02 02:13:05 - [Task] Id:120 Name:OPT_VIM_1HEAD Exception with index:18 | 18.9251137 | Exception:
ERROR connection to partner '10.19.101.17:3300' broken
2022-09-01 23:13:25Z | error | 2022-09-02 02:13:25 - [Task] Id:121 Name:OPT_VIM_1ITEM
ERROR connection to partner '10.19.101.22:3300' broken
2022-09-01 23:13:25Z | error | 2022-09-02 02:13:25 - [Task] Id:121 Name:OPT_VIM_1ITEM RunId:7 Task execution failed with error: One or more errors occurred., detail:
ERROR connection to partner '10.19.101.22:3300' broken
'# -split '\r?\n'
# Process each line...
$logLines | ForEach-Object {
# ... by matching it ($_) against a regex with capture groups - (...) -
# using the -match operator.
if ($_ -match '\| (\d{4}-.+?) - \[.+? Name:(\w+)') {
# The line matched.
# Capture groups 1 and 2 in the automatic $Matches variable contain
# the tokens of interest; assign them to variables.
$timestamp = $Matches.1
$jobName = $Matches.2
# Sample output, as an object
[PSCustomObject] #{
JobName = $jobName
Timestamp = $timestamp
}
}
}
Output:
JobName Timestamp
------- ---------
OPT_VIM_1HEAD 2022-09-02 02:13:05
OPT_VIM_1ITEM 2022-09-02 02:13:25
OPT_VIM_1ITEM 2022-09-02 02:13:25
For an explanation of the regex and the ability to experiment with it, see this regex101.com page.
I have following content in my csv file(with 3 columns):
141413,"\"'/x=/></script></title><x><x/","Mountain View, CA\"'/x=/></script></title><x><x/"
148443,"CLICK LINK BELOW TO ENTER^^^^^^^^^^^^^^","model\
\
xxx lipsum as it is\
\
100 sometimes unknown\
\
travel evening market\
"
When I import above mentioned csv in mysql using following command, it treats the backslash() as new line; which is the expected behavior.
LOAD DATA INFILE '1.csv' INTO TABLE users FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n';
MYSQL Output
But when I try to import to psql using copy command, it treats \ as a normal character.
copy users from '1.csv' WITH (FORMAT csv, DELIMITER ',', ENCODING 'utf8', NULL "\N", QUOTE E'\"', ESCAPE '\');
postgres Output
Try parsing these \ before importing the CSV file, e.g. using perl -pe or sed and the STDIN from psql:
$ cat 1.csv | perl -pe 's/\\\n/\n/g' | psql testdb -c "COPY users FROM STDIN WITH (FORMAT csv, DELIMITER ',', ENCODING 'utf8', NULL "\N", QUOTE E'\"', ESCAPE '\');"
This is how it looks like after the import:
testdb=# select * from users;
id | company | location
--------+-----------------------------------------+-------------------------------------------------
141413 | "'/x=/></script></title><x><x/ | Mountain View, CA"'/x=/></script></title><x><x/
148443 | CLICK LINK BELOW TO ENTER^^^^^^^^^^^^^^ | model +
| | +
| | xxx lipsum as it is +
| | +
| | 100 sometimes unknown +
| | +
| | travel evening market +
| |
(2 Zeilen)
I´m new to Xtext and have a problem.
When I try to create a terminal String without quotes I always get EOF errors.
If I comment out the code for the String without quotes I´dont get an error and everything works fine.
Can someone explain me this?
Or give me some hint how I could better solve this?
Thank you very much
// String without quotes
terminal STRINGWQ: ( ('a'..'z'|'A'..'Z')('a'..'z' | 'A'..'Z' | '_'| '-' | '§' | '?' | '!'| '#'
| '\n' | ':' |'%' | '.' | '*' | '^' | ',' | '&' | '('|')'| '0'..'9'|' ')*);
Rest of Code
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
(elements += GITest)*
;
GITest:
KWHeader | KWTestCase
;
// KeyWords Header
KWHeader:
'Test' '!''?'
;
KWTestCase:
'testcase' int=INT ':' title = ID |
'Hello' names=ID '!'
;
UPDATE:
Data Type Rule
QSTRING returns ecore::EString: //custom terminal SurveyString
(('a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'|
'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'|' ')
('a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'|
'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'|
' '|'_'|'-'|'§'|'?'|'!'|'#'|'%'|'.'|'*'|'^'|','|'&'|'('|')'|'0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')*);
UPDATE 2:
Got it working with Data Type Rule und manipulating ID
Code:
STRINGWQ: ((' ')?ID)((ID)?(INT)? ' ' (ID)?);
terminal ID: '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'/'|';'|','|'#'|'!'|'§'|'$'|'%'|'&'|
'('|')'|'='|'?'|'\\'|'*'|'+'|'.'|'-'|'>'|'<'|'|'|'['|']'|'{'|'}')*;
But now I have the problem that xtext not recognizes when STRINGWQ ends.
So I dont get keyword suggestions in the next line.
For example if i dont use STRINGWQ but INT I get suggestions in the next line.
But with STRINGWQ I dont.
How can I define an end of Data Type Rules?
Thank you
Your STRINGWQ shadows the terminal rule ID and basically all other rules including the keywords. Chances are good that the entire document will by consumed as a single terminal token of type STRINGWQ. You should try to model your string as a datatype rule.
This works for me:
Property:
id=ID | int=INT | prop=PROPERTY_VALUE | spec=SPECIAL;
PROPERTY_VALUE:
(':');
SPECIAL:
(' ' | '/' | ';' | ',' | '!' | '§' | '%' | '&' | '(' | ')' | '?' | '*' | '+' | '.' | '-' | '|' | '[' | ']')
I separated the colon as I need to use PROPERTY_VALUE in another way.
But you also could add it to special.
I've written a grammar which should allow me to define variables and arrays. Everything worked fine until I split up the variables into local and global variables. Now my parser doesn't recognize the arrays anymore (it says it would be a variable and gives me syntax errors for that).
My Grammar:
grammar sqf.Sqf with org.eclipse.xtext.common.Terminals
generate sqf "http://www.Sqf.sqf"
Model:
elements += Element*
;
Element:
Declaration ";" | Command ";"
;
Declaration:
Array | Variable
;
Variable:
LocalVariable | GlobalVariable
;
LocalVariable:
name=LOCALVARNAME "=" content=VARCONTENT (("+"|"-"|"*"|"/") content2+=VARCONTENT)*
;
GlobalVariable:
name=GLOBALVARNAME "=" content=VARCONTENT (("+"|"-"|"*"|"/") content2+=VARCONTENT)*
;
Array:
name=ID "=" content=ArrayLiteral | name=ID "=" "+" content2=[Array]
;
ArrayLiteral:
"[" (content += ArrayContent)* "]" (("+"|"-")content1+=Extension)*
;
ArrayContent:
content01=Acontent ("," content02+=Acontent)*
;
Acontent:
STRING | DOUBLE | ArrayLiteral
;
Extension:
STRING | DOUBLE
;
Command:
Interaction
;
Interaction:
hint
;
hint:
Normal | Format | Special
;
Normal:
name=("hint" | "hintC" | "hintCadet" | "hintSilent") content=STRING
;
Format:
name=("hint" | "hintC" | "hintCadet" | "hintSilent") "format" "[" content=STRING "," variable=DECREF "]"
;
Special:
hintCArray
;
hintCArray:
title=STRING "hintC" (content1=ArrayLiteral | content=STRING)
;
VARCONTENT:
STRING | DOUBLE | DECREF | "true" | "false" | "nil"
;
DOUBLE:
INT ("."INT)?
;
DECREF:
ref1=[Array|ID] | ref2=[LocalVariable|LOCALVARNAME] | ref3=[GlobalVariable|GLOBALVARNAME]
;
terminal LOCALVARNAME:
"_" ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
;
terminal GLOBALVARNAME:
'^'?('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
;
Has anybody of you an idea what the problem is?
(Any other code improvements are welcome, too)
Greets Krzmbrzl
Your rule GLOBALVARNAME completely shadows the rule ID. You could simply use ID instead of GLOBALVARNAME.