foreach random no match - foreach

This is for code:
set source_failed = `cat mine.log`
set dest_failed = `cat their.log`
foreach t ($source_failed)
set isdiff = 0
set sflag = 0
foreach t2 ($dest_failed)
if ($t2 == $t) then
set sflag = 1
break
endif
end
...
end
Problem is that the inner foreach loop runs okay for first few 10 iterations. After that iteration, suddenly I got
foreach: no match
Moreover, I am iterating over the array of strings, not files. What is the reason behind this error?

The problem is (probably) that mine.log and/or their.log contain special globbing characters, such as * or ?. The shell will try to expand this to a file. There are no matches for this accidental pattern, and hence the error "no match".
The easiest way to prevent this behaviour is to add set noglob to the top. From tcsh(1):
noglob If set, Filename substitution and Directory stack substitution
(q.v.) are inhibited. This is most useful in shell scripts
which do not deal with filenames, or after a list of filenames
has been obtained and further expansions are not desirable.
You can re-enable this behaviour by using set glob.
Alternativly, you can use :q. From tcsh(1):
Unless enclosed in `"' or given the `:q' modifier the results of variable
substitution may eventually be command and filename substituted.
[..]
When the `:q' modifier is applied to a substitution the variable will expand
to multiple words with each word sepa rated by a blank and quoted to
prevent later command or filename sub stitution.
But you need to be very careful about quoting when you use the variable. In the below example, the echo command will fail if you don't add quotes (set noglob is much easier):
set source_failed = `cat source`
foreach t ($source_failed:q)
echo "$t"
end

Related

Use shell variable in grep lookahead in csh

I am trying to utilize a grep lookahead to get a value at the end of a line for a project I'm working on. The main issue I'm having is that I'm not sure how to use a shell variable in the grep lookahead syntax in cshell
Here's the gist of what I'm trying to do.
There will be a dogfile.txt with several lines listing the names of dogs in the format below
genericDog2033, pomeranian
genericDog2034, greatDane
genericDog2035, Doberman
I wanted a way of retrieving the breed of the dog after the comma on each line so I thought a grep lookahead might be a good way of doing it. The project I'm working on isn't so hard-coded however, so I have no way of knowing what genericDog number I am searching for. There will be a shell variable in a greater while loop which will have access to the dog name.
For example if I set the dogNumber variable to the first dog in the file like so:
set dogNumber = genericDog2033
I then try to access the value of dogNumber in the grep lookahead
set dogBreed = `cat File.txt | grep -oP '(?<=$dogNumber ,)[^ ]*'`
The problem with the line above is that I think grep is looking for the literal string "$dognumber ," in the file which obviously doesn't exist. Is there some sort of wrapper I can put around the shell variable so cshell knows that dogNumber is a variable? I'm also open to other methods of doing this. Any help would be appreciated, this is the literal last line of code I need to finish my project and I'm at my wits end.
Variable expansion only happens inside double quotes ("), and not single quotes ('):
% set var = 'hello'
% echo '$var'
$var
% echo "$var"
hello
Furthermore, you have an error in your regexp:
(?<=$dogNumber ,)[^ ]*
In your data, the space is after the comma, not before.
% set dogNumber = genericDog2033
% set dogBreed = `cat a | grep -oP "(?<=$dogNumber, )[^ ]*"`
% echo $dogBreed
pomeranian
The easiest way to debug this is to not use variables at all in the first place, and simply check if the grep works:
% grep -oP "(?<=genericDog2034 ,)[^ ].*" a
[no output]
Then first make the grep work with static data, add the variable to make that work, and then put it all together by assigning it to a variable.

Jenkins conditional steps token logic operators

I inject environmental variable from a file myprop.property that has the contents:
var1=y
var2=y
The build steps:
1. Inject environment variables:
Property File Path:${JENKINS_HOME}/myprop.propertie
Execute Windows batch command (to verify variable injected successully)
echo var1 = %var1% echo var2 = %var2%
Condition steps (multiple)
Run?: Boolean condition
Token: ${ENV,var="var1"}||${ENV,var="var2"}
Steps to run if condition is met: echo Yes, works!
Run the build, the condition in step 3 never met while step 2 display the correct values of the variables.
I have tried the conditions and operators:
var1=y, var2=y: ${ENV,var="var1"}||${ENV,var="var2"}
var1=y, var2=y: ${ENV,var="var1"}|${ENV,var="var2"}
var1=y, var2=n: ${ENV,var="var1"}||${ENV,var="var2"}
var1=y, var2=n: ${ENV,var="var1"}|${ENV,var="var2"}
Uppercase or lower case of the values do not make any difference. I am running jenkins 1.641 on windows 7 pro.
If I use only one e.g. ${ENV,var="var1"} in the token field, it works as expected.
Try this instead, It worked for me, we need to mention Boolean Condition with Token mentioned in the image.
This works, change step 3 to:
Run?: Or
Boolean condition
Token: ${ENV,var="var1"}
Or
Boolean condition
Token: ${ENV,var="var2"}
Never
these are actually three conditions. the execution asserts the first condition first, if it's met, stop checking; if not met, asserts the second; and so on until the last condition that is Never, meaning if no condition is met, stop executing the step.
I see my post attracted lots interests. Here are what I eventually worked around.
Use Regular expression match seems to be more readable than using Boolean Condition.
If the logic is an "OR",
? = Regular expression match
expression = ${ENV,var="var1"}|${ENV,var="var2"}
Label = Y
Note that the logic operator is a single '|', not double '||'.
if the logic is an "AND",
? = Regular expression match
expression = ${ENV,var="var1"}${ENV,var="var2"}
Label = YY
The expression is just concatenation of the two variables, and the Label is so as well.

Lua cmd-line string

Say I call Lua with this cmd:
luajit neuralnetwork.lua --satEpoch "somestring" --maxEpoch 50
How can I access this same cmd-line string from Lua?
I know about the arg table, but it removes all quotes from the original command string making it difficult to reconstruct:
{
"--maxEpoch"
"--satEpoch"
"50"
"somestring"
[-1] : "luajit"
[0] : "examples/neuralnetwork.lua"
}
If I can save the exact string to a file from within Lua, I can easily call it again later.
#peterpi is correct that the shell is interpreting the command and as a result stripping away the quotes. However, reconstructing the command exactly is not really necessary to have the shell interpret the command the same way as before.
For simple cases concatenating the arguments to the script is often enough:
local command = table.concat(arg, ' ', -1, #arg)
This will fail if the quotes are actually necessary, most commonly when an argument contains a space or shell character, so quoting everything is easy and somewhat more robust, but not pretty.
Here is an example with a Lua pattern to check for special (bash) shell characters and spaces to decide if and which quotes are necessary. It may not be complete but it handles filenames, most strings, and numbers as arguments.
local mod_arg = { }
for k, v in pairs(arg) do
if v:find"'" then
mod_arg[k] = '"'..v..'"'
elseif v:find'[%s$`><|#]' then
mod_arg[k] = "'"..v.."'"
else
mod_arg[k] = v
end
end
local command = table.concat(mod_arg, ' ', -1, #mod_arg)
print(command)
No doubt somebody will prove me wrong, but generally I don't think this is possible. It's the shell rather than luajit that takes the quotes away and chops the line up into individual tokens.

Create virtualedit block around selection

I'm trying to create a script what permits me to select a few lines and create a virtualedit block around it; 1 column after the longest line.
This is my code
function! VirtualEdit()
let EndLine = line("'>")
set virtualedit = all
let maxlength = max(map(range(line("'<"), line("'>")), "virtcol([v:val, '$'])"))-1
call cursor(1,maxlength+1)
normal "^Q".EndLine."jc<space><ESC>"
set virtualedit = ''
endfunction
What it must do is
1) Control the longest line in my selection (maxlength).
2) Put the cursor on the first line in the selection at the column of the longest line +1 column.
3) Than Activate Visual Block selection (on my windows pc the command is C-Q)
4) Extend the visual block till the last line in the selection (the command on my pc for moving down = "j").
5) Than use the "c" key to insert a "space" character and ESC to exit the insert mode in order to fill the virtual block column with spaces.
However I can't find out how to use a variable (Endline) in a normal command.
I noted also that keys as and don't work in my above example.
What did I wrong?
You have many errors here:
:set does not let you have spaces around =
:set does not accept expressions, thus set ve='' is let &ve="''", not let &ve='' which is :set ve=.
:normal command also does not accept expressions, it accepts strings that are just executed. Thus :normal "^ is trying to use register ^, fails (no such register) and stops processing the rest of the line. Use :execute to pass expressions to :normal.
:normal command does not accept <Key> syntax. Neither do viml expressions, they have "\<Key>" instead (note: only double quotes and with backslash). ^Q syntax is not accepted by anybody and having raw control codes (displayed by vim as ^Q) inside a text file is not the best idea.
Don’t use :normal without a bang. Most of time you don’t need it (you need to replace ^Q with \<C-v> in this case though because it is a mapping).
Don’t hardcode virtualedit value. Instead of
set ve=all
<...>
set ve=
use
let savedve=&ve
set ve=all
try
<...>
finally
let &ve=savedve
endtry
{N}j means “N lines down”, not “go to N’th line”. “Go to N’th line” is {N}gg or {N}G.
You have let maxlen=<...>-1 and the on only line where maxlen is used you have maxlen+1. It is strange.
If you fix this you can proceed, but you don’t need adjusting virtualedit and using :normal at all:
function AddSpaces()
let [lstart, lend]=[line("'<"), line("'>")]
if lstart>lend
let [lstart, lend]=[lend, lstart]
endif
let maxcol=max(map(range(lstart, lend), "virtcol([v:val, '$'])"))
let newlines=map(range(lstart, lend), 'printf("%-'.maxcol.'s", getline(v:val))')
call setline(lstart, newlines)
endfunction

Easiest way to remove Latex tag (but not its content)?

I am using TeXnicCenter to edit a LaTeX document.
I now want to remove a certain tag (say, emph{blabla}} which occurs multiple times in my document , but not tag's content (so in this example, I want to remove all emphasization).
What is the easiest way to do so?
May also be using another program easily available on Windows 7.
Edit: In response to regex suggestions, it is important that it can deal with nested tags.
Edit 2: I really want to remove the tag from the text file, not just disable it.
Using a regular expression do something like s/\\emph\{([^\}]*)\}/\1/g. If you are not familiar with regular expressions this says:
s -- replace
/ -- begin match section
\\emph\{ -- match \emph{
( -- begin capture
[^\}]* -- match any characters except (meaning up until) a close brace because:
[] a group of characters
^ means not or "everything except"
\} -- the close brace
and * means 0 or more times
) -- end capture, because this is the first (in this case only) capture, it is number 1
\} -- match end brace
/ -- begin replace section
\1 -- replace with captured section number 1
/ -- end regular expression, begin extra flags
g -- global flag, meaning do this every time the match is found not just the first time
This is with Perl syntax, as that is what I am familiar with. The following perl "one-liners" will accomplish two tasks
perl -pe 's/\\emph\{([^\}]*)\}/\1/g' filename will "test" printing the file to the command line
perl -pi -e 's/\\emph\{([^\}]*)\}/\1/g' filename will change the file in place.
Similar commands may be available in your editor, but if not this will (should) work.
Crowley should have added this as an answer, but I will do that for him, if you replace all \emph{ with { you should be able to do this without disturbing the other content. It will still be in braces, but unless you have done some odd stuff it shouldn't matter.
The regex would be a simple s/\\emph\{/\{/g but the search and replace in your editor will do that one too.
Edit: Sorry, used the wrong brace in the regex, fixed now.
\renewcommand{\emph}[1]{#1}
any reasonably advanced editor should let you do a search/replace using regular expressions, replacing emph{bla} by bla etc.

Resources