Does anyone know the best place where I can go to see the differences between the variations of JEXL? I've noted the following so far.
Expression
This only allows for a single command to be executed and the result from that is returned. If you try to use multiple commands it ignores everything after the first semi-colon and just returns the result from the first command.
Script
This allows you to put multiple commands in the expression and you can use variable assignments, loops, calculations, etc. The result from the last command is returned from the script.
Unified
This is ideal for text. To get a calculation you use the EL-like syntax as in ${someVariable}. The expression that goes between the brackets behaves like a script, not an expression. You can use semi-colons to execute multiple commands and the result from the last command is returned from the script.
Related
For example I want replace any prompt function in an SQL query
I have used this expression
Query = Query.replaceAll("#prompt\\s*\\(.*?\\)", "(1)");
This expression works in this example
#Prompt('Bill Cycle','A','MIGRATION\BC',,,)
#Prompt('Bill Cycle','A','MIGRATION\BC',,,)
and the output is is (1)
but when it does not work on this example
#Prompt('Groups','A','[Lookup] Price Group (2)\Nested Group',,,)
the out put is (1) \Nested Group',,,) which is not valid
Sadly, as pointed out by Joe C in a comment, what you are trying to do cannot be done in a regular expression for arbitrary depth parenthesis. The reason is because regular-expressions are not capable of "counting". You need a stack machine for that, or a context-free language parser.
However, you also suggest that the 'prompted' content is always inside single quotes. I assume below the standard Java regexp library. Other regexp libraries might need translation...
"#Prompt\\('[^']*'(\s*,\s*(('[^']*')|([^',)]*)))*\\)"
So, you are searching within prompt for blocks of single-quoted text. The search assumes that each internal bit of content is enclosed in single quotes.
Verify at https://regex101.com/r/nByy0Y/1 (I made a couple fixes). Note that at regex101.com, it will treat the double back-slash as intending a literal back-slash. What you want instead is just to quote the parenthesis so that you want a literal parenthesis.
Because you are using the lazy quantifier '?', it is stopping the match at the end of the first ')'. removing that will let it go to the end greedily, as such:
#prompt\(.*\)
But if there is concern that the entries may have more parans after the one in question, it will cause problems.
Assuming the additional parens will always be in quotes, you can do this:
#prompt\((('([^'])*',*)*|(.*,*)*)\)
Here is it looking for items wrapped in single quotes OR text without parens, which should capture all of the single quoted elements or null params or unquoted text params
I'm modifying an application backout script in JACL. This script is designed to search for a JVM argument string that we want to remove within the JVM arguments of the server. New to the application this release cycle is a jvm argument ${variable_name}. My old code
set ixReplace [lsearch -exact $jvm_args "string_to_search"]
set jvm_args [lreplace $jvm_args $ixReplace $ixReplace]
now returns an extra set of {} like this
-Xjit:disableOSR -Xgc:preferredHeapBase=0x100000000 -Xmnx1152m -Xmns512m
-Xgcpolicy:gencon -agentlib:getClasses -noverify {${variable_name}}
I've found multiple articles about how to remove the extra {} here and here but I cannot seem to set the results to a variable to which i'm using to set new jvm arguments.
My ultimate goal is to have the correct string set to a variable called jvm_args so that I may use to update the JVM arguments like this.
set attr {}
lappend attr [list genericJvmArguments $jvm_args]
$AdminConfig modify $server_jvm_id $attr
Any help or suggestions would be greatly appreciated.
Tcl's adding those braces because you've got a well-formed Tcl list after the lreplace operation, and not any old string. The braces stop the ${variable_name} from ever being interpreted as a variable substitution; the $ is a Tcl metasyntax character. (Square brackets would also attract quoting, as would a few other characters too.)
However, you're wanting to feed the result into a context that doesn't expect a Tcl list, but rather probably a simple space-separated string. The simplest approach is to just use join at the point where you stop thinking of having a Tcl list of words and start thinking of having a general string, probably like this:
lappend attr [list genericJvmArguments [join $jvm_args]]
It won't cope well if you've got spaces embedded in the string, or a few other cases, but without knowing the exact criteria for what makes a word a word in the source material or how to quote things in the system that is taking them, this is the best you're likely to get. (It is at least cheap to do this much…)
I need to use Java to rsync several files using one command
the following command works fine in shell
rsync -avrz --timeout=100 rsync://10.149.21.211:8730/'logflow/click/file1 logflow/click/file2' /home/kerrycai/puller"
but when i use the following Java code , it does not work
String cmd = "rsync -avrz --timeout=100 rsync://10.149.21.211:8730/'logflow/click/file1 logflow/click/file2' /home/kerrycai/puller";
Process p = Runtime.getRuntime().exec(cmd);
int ret = p.waitFor();
the ret value is not equal to 0 (5 in my test), and the command is not executed succeed, after some debugging , it seem the problem is caused by the single quote
So, my questions is
Can I using java to execute a shell command which has single quote in it (Pls note, the single quote is in the middle of a parameter, not start/end) ?
Can I have a shell command to rsync several files in one command , and the command does not have single(double) quotes in it ?
Note to #Chris: this combination of multiple filenames (really modified-partly-like-filenames) in one argument is indeed very unusual and even 'suspicious' for Unix in general, but is (or at least was) correct for rsync in particular.
Preface: Java Runtime.exec does NOT 'execute a shell command' (unless you explicitly run a shell and give it a command); it runs a program, with arguments. These different things are often confused because most of the shell commands used by normal users are commands to run programs, but this is one case where the difference matters. In particular quoting a space to shell causes the shell to pass a single argument to the program containing the space instead of splitting into two (or more) arguments, but the quote itself is NOT included in the argument.
First you should look at the man page (on your system or online at https://download.samba.org/pub/rsync/rsync.html) under ADVANCED USAGE. Current (and IME even moderately old) versions of rsync have a more convenient syntax with separate arguments to get multiple files, which the simple parsing used by Runtime.exec(String) can handle like this:
rsync -avrz --timeout=100 --port=8730 10.149.21.211::logflow/click/file1 ::logflow/click/file2 /home/kerrycai/puller
But if you need (or really want) to use the quoted-space form then you need to do the tokenization yourself and use the String[] overload as suggested by #EJP -- although you can still use Runtime, you don't need ProcessBuilder for this. Specifically do something along the lines of:
String[] cmdarray = {"rsync",
"-avrz",
"--timeout=100",
"rsync://10.149.21.211:8730/logflow/click/file1 logfile/click/file2",
// separated argument contains space but not single (or other) quote
"/home/kerrycai/puller" };
... Runtime.getRuntime.exec(cmdarray); ...
You're calling a somewhat large command from Java. Why not just use a shell script? Put your gnarly command in myScript.sh and then have Java invoke /bin/bash myScript.sh. Makes all the weirdness to do with string handling in Java go away.
We are developing an eclipse plugin tool to remove sysout statements from the workspace projects. We are able to achieve our goal only partially. If the sysouts are in one line we are able to delete it easily. But if the sysout is spanned over a couple of lines (generally occurs due to code formatting), this is when we face the issue.
For Example :
System.out.println("Hello World");
The regular expression to remove this line would be simple:
System.out.println*
But if the code is this:
System.out.println(New Line)("HelloWorld");
This is where the issue comes. Can anyone please suggest how I can replace this using a java regular expression.
I suggest
String regex = "System\.out\.println[^)]+[)]\s*;"
Where the [^)]+ will scan until the closing parenthesis. However, this will fail in multiple cases:
(possibly-unbalanced) parenthesis inside the output
commented-out code
the few cases where it is possible to omit the ';'
cases where System.out is assigned to another variable, instead of being used directly
Go the extra mile and use a Eclipse's in-built parser (which understands lexical issues, comments, and can flag any compile-time references to System.out).
I have a .sh script with a property=value. Let it be:
some_property="some value"
The value of the property is used along the script and script is launched in Java code. I want to dynamically change this property's value. I tried to use replaceFirst() method, but I don't know the actual value of "some_property" to replace it correctly using regexp.
How can I edit a .sh file with replacing a single line that starts with "some_property=" by some_property=my_value? By the way there're several places in a file where pattern "some_property=" can be met, so I need to change the first occurrence.
You should be fine with a regex:
line.replaceFirst("some_property=.*$", "some_property=\"" + your_value + "\"");
You can get position of the = and \n using String.indexOf(int) and then replace the string between = and \n using, for example, replace(CharSequence, CharSequence).
Btw - some_property=(.+) (and replacing $1) wouldn't be okay? :)