Is there an API for grep, pipe, cat in groovy? - unix

Is there an API for grep, pipe, cat in groovy?

Not sure I understand your question.
Do you mean make system calls and pipe the results?
If so, you can just do something like:
println 'cat /Users/tim_yates/.bash_profile'.execute().text
To print the contents of a file
You can pipe process output as well:
def proc = 'cat /Users/tim_yates/.bash_profile'.execute() | 'grep git'.execute()
println proc.text
If you want to get the text of a File using standard Groovy API calls, you can do:
println new File( '/Users/tim_yates/.bash_profile' ).text
And this gets a list of the lines in a file, finds all that contain the word git then prints each one out in turn:
new File( '/Users/tim_yates/.bash_profile' ).text.tokenize( '\n' ).findAll {
it.contains 'git'
}.each {
println it
}

Related

bjam - cannot assign a literal to a variable?

Well, this must be the most stupid and idiotic behavior I've seen from a programming language.
https://www.bfgroup.xyz/b2/manual/release/index.html says:
Syntactically, a Boost.Jam program consists of two kinds of
elements—keywords (which have a special meaning to Boost.Jam) and
literals. Consider this code:
a = b ;
which assigns the value b to the variable a. Here, = and ; are
keywords, while a and b are literals.
⚠ All syntax elements, even
keywords, must be separated by spaces. For example, omitting the space
character before ; will lead to a syntax error.
If you want to use a literal value that is the same as some keyword,
the value can be quoted:
a = "=" ;
OK, so far so good. So I have this in my Jamroot:
import path : basename ;
actions make_mytest_install
{
echo "make_mytest_install: MY_ROOT_PATH $(MY_ROOT_PATH) PWD $(PWD:E=not_set)" ;
epath = "$(MY_ROOT_PATH)/projects/mytest/bin/gcc-9/release/qt5client" ;
ename = basename ( $(epath) ) ;
echo "epath $(epath) ename $(ename)" ;
}
explicit install-gettext ;
make install-mytest : : #make_mytest_install ;
... and I try this:
bjam install-mytest
...updating 1 target...
Jamfile</home/USER/src/myproject>.make_mytest_install bin/install-mytest
make_mytest_install: MY_ROOT_PATH /home/USER/src/myproject PWD not_set
[ SHELL pstree -s -p 2720269 && echo PID 2720269 PWD /home/USER/src/myproject ]
/bin/sh: 13: epath: not found
/bin/sh: 14: Syntax error: "(" unexpected
.....
...failed Jamfile</home/USER/src/myproject>.make_mytest_install bin/install-mytest...
...failed updating 1 target...
Now - how come that the SIMPLEST assignment to a string, EXACTLY AS in the manual:
epath = "$(MY_ROOT_PATH)/projects/mytest/bin/gcc-9/release/qt5client" ;
... fails, and this variable cannot be found anymore?
What is the logic in this? How the hell is this supposed to work? I would get it if MY_ROOT_PATH was undefined - but the echo before it, shows that it is not? What is this lunacy?
So I cannot believe I'm asking something this trivial, but:
How do you assign a string to a variable in bjam language?
Well, the error gives somewhat of a hint: /bin/sh: -> so apparently inside actions, it is sh that runs - then again, if it was really sh I could have assigned variables, but I can't. So best I could do, was to remove the assignments OUT of actions:
import path : basename ;
epath = "$(MY_ROOT_PATH)/projects/mytest/bin/gcc-9/release/qt5client" ;
# ename = basename ( $(epath) ) ; # nope, causes target install-mytest to not be found :(
# calling a shell for basename works - but adds a damn NEWLINE at end!?!?!?!
ename = [ SHELL "basename $(epath)" ] ;
actions make_mytest_install
{
echo "make_mytest_install: MY_ROOT_PATH $(MY_ROOT_PATH) PWD $(PWD:E=not_set)" ;
echo "epath $(epath) ename $(ename)" ;
}
explicit install-mytest ;
make install-mytest : : #make_mytest_install ;
So, assignment kind of passes, but you still can't get the basename ?!
I still don't understand, who thought this kind of variable management is a good idea ... I don't even understand, how people managed to build stuff with this system

zsh completion complete literal quotes

I am writing my own completions for a program.
I would like to be able to complete quoted words, maintaining the double or single quotes in the completion.
#compdef foo
_foo {
local strings
strings=(\
foo\
bar\
'spam eggs')
_arguments \
{-s,--string}'[Select a string]:STR:(\""${strings[#]}"\")\
&& return 0
}
_foo
what I'd expect:
foo -s <TAB>
"foo" "bar" "spam eggs"
what it get:
\"foo\" \"bar\" \"spam\ eggs\"
I ended up trying different combinations of nested quotes and escapes almost brainlessly but with no luck, as I was not able to find the relevant docs (really, zsh docs are "dense")
Thank you!

What is it called when you have multiple data structures, but not connected with json in jq?

For instance, I might have something coming out of my jq command like this:
"some string"
"some thing"
"some ping"
...
Note that there is no outer object or array and no commas between items.
Or you might have something like:
["some string"
"some thing"
"some ping"]
["some wing"
"some bling"
"some fing"]
But again, no commas or outer object or array and no commas between them to indicate that this is JSON.
I keep thinking the answer is that it is called "raw", but I'm uncertain about this.
I'm specifically looking for a term to look for in the documentation that allows you to process the sorts of examples above, and I am at a loss as how to proceed.
To start with, the jq manual.yml describes the behavior of filters this way:
Some filters produce multiple results, for instance there's one that
produces all the elements of its input array. Piping that filter
into a second runs the second filter for each element of the
array. Generally, things that would be done with loops and iteration
in other languages are just done by gluing filters together in jq.
It's important to remember that every filter has an input and an
output. Even literals like "hello" or 42 are filters - they take an
input but always produce the same literal as output. Operations that
combine two filters, like addition, generally feed the same input to
both and combine the results. So, you can implement an averaging
filter as add / length - feeding the input array both to the add
filter and the length filter and then performing the division.
It's also important to keep in mind that the default behavior of jq is to run the filter you specify once for each JSON object. In the following example, jq runs the identity filter four times passing one value to it each time:
$ (echo 2;echo {}; echo []; echo 3) | jq .
2
{}
[]
3
What is happening here is similar to
$ jq -n '2, {}, [], 3 | .'
2
{}
[]
3
Since this isn't always what you want, the -s option can be used to tell jq to gather the separate values into an array and feed that to the filter:
$ (echo 2;echo {}; echo []; echo 3)| jq -s .
[
2,
{},
[],
3
]
which is similar to
$ jq -n '[2, {}, [], 3] | .'
[
2,
{},
[],
3
]
The jq manual.yml explains how the --raw-input/-R option can be included for even more control over input handing:
Don't parse the input as JSON. Instead, each line of text is passed to the filter as a string. If combined with --slurp,then the entire input is passed to the filter as a single long string.
You can see using the -s and -R options together in this example produces a different result:
$ (echo 2;echo {}; echo []; echo 3)| jq -s -R .
"2\n{}\n[]\n3\n"

Get name of calling function in zsh

I want to get function caller name in shell script sometime, in bash it works with ${FUNCNAME[1]}
${FUNCNAME[1]} is a (caller name)
${FUNCNAME[0]} is c (current name)
but it not work in zsh
ie i want to know which function call me in function c
function a(){
c
}
function b(){
c
}
function c(){
#if a call me; then...
#if b call me; then...
}
The function call stack is in the variable $funcstack[].
$ f(){echo $funcstack[1];}
$ f
f
So in c the calling function (a or b) is $funcstack[2] or perhaps more conveniently $funcstack[-1].
Generic solution
Works whether array indexing starts at 0 (option KSH_ARRAYS) or 1 (default)
Works in both zsh and bash
# Print the name of the function calling me
function func_name () {
if [[ -n $BASH_VERSION ]]; then
printf "%s\n" "${FUNCNAME[1]}"
else # zsh
# Use offset:length as array indexing may start at 1 or 0
printf "%s\n" "${funcstack[#]:1:1}"
fi
}
Edge case
The difference between bash and zsh is that when calling this function from a sourced file, bash will say source while zsh will say the name of the file being sourced.

Is there a way to jump to the end of a sourced script without killing entire execution in R?

Suppose I have a script Foo.r which looks like this.
source('Bar.r')
print("Hello World")
Now suppose further that in Bar.r, I want to return immediately if some condition is true, instead of executing the rest of the script.
if (DO_NOT_RUN_BAR) return; // What should return here be replaced with?
// Remainder of work in bar
In particular, if DO_NOT_RUN_BAR is set, I want Bar.r to return and Foo.r to continue execution, printing Hello World.
I realize that one way to do this is to invert the if statement in Bar.t and wrap the entire script inside an if statement that checks for the logical negation of DO_NOT_RUN_BAR, but I still want to know whether I can replace the return statement in the code above to skip execution of the rest of Bar.r when it is sourced.
By defintion , source parse a file until the end of the file.
So, I would split bar file in 2 parts :
source("bar1.R")
if (DO_RUN_BAR2) source("bar2.R")
print("Hello World")
This is safer than managing global variables with dangerous side effect.
In Bar.r you can do
if (DO_NOT_RUN_BAR) stop();
Then in Foo.r you call it like this
try(source("./bar.r"), silent=T)
Create your script with a multi-line expression with {...} enclosing it, and use stop in the middle:
{ print("test")
print("test")
print("test"); stop()
print("test")
print("test")
print("test") }
#[1] "test"
#[1] "test"
#[1] "test"
#Error:

Resources