Subtracting count values in UNIX - unix

I am trying to subtracts one count value from another but,I am facing problem in following code :
count=$?
count1=$?
(then some operations and above count values got some value suppose 1,2 respectively)
$count=$count1 - $count ==> Here it should get : 2-1=1 )
I don't know exact syntax for this so, can any one help me please?

You can use the shell's expression syntax:
count=$(($count1-$count))
the $ prefix on variables is optional inside $(()), so this can also be written as:
count=$((count1-count))

Unix provides you the command expr that lets you evaluate any arithmetic expression you want. At shell prompt try :
expr 2 - 3 + 5 '*' 8
Remember that * is used as wildcard so you need to un-specialized it in any way you want.
Then now, you could use ` to evaluate an expression at any place :
count=`expr $count1 - $count`
Be aware that all arguments MUST be separated with spaces.
This will work for Bourne-shell which is the one recommended for shell-scripts.

Related

Why ${(%):-%N} to get expansion of % escapes in zsh?

To get the path of a currently running script people suggest to use ${(%):-%N}. I have looked into this and I cannot wrap my head around why ${(%)%N} shouldn't work.
From reading the manual (zshexpn) it seems like the above command uses ${name:-value} which returns the value of name if this is set (and non-null), otherwise value. In the case above name is left blank, in which case value is always returned.
The first (%) is a parameter expansion flag that (as far as I understand) should make all % escapes (%N in this case) expand in the same way as in the prompt.
Shouldn't it be possible to simply use ${(%)%N} instead? This does not work, but I do not understand why.
Can anyone shed any light on this? Perhaps my understanding of how ${(%):-%N} is parsed is not correct?
The syntax ${...} is for a parameter expansion, and in this case %N is not a parameter - it's a string literal. The :- syntax is a way to turn a string literal into a parameter.
Some examples that may help explain this:
> parm='%N'
> print ${parm}
%N
> print -- ${(%)parm}
-zsh
> print X${notaparameter}X
XX
> print X${%N}X
XX
> print X${:-%N}X
X%NX
> print X${(%):-%N}X
X-zshX

Grako left recursion

I'm trying to use grako to describe a simple left-recursive grammar but I have trouble to do so.
Right-recursion does work without any problem :
symbol = /[a-z]/ ;
condition = symbol "AND" condition | symbol ;
start = condition $ ;
According to all examples I found, left-recursion should be described this way :
symbol = /[a-z]/ ;
condition = condition "AND" symbol | symbol ;
start = condition $ ;
However, it does not work for the rule given below :
a AND b AND c
I get this error :
grako.exceptions.FailedParse: srecur(1:3) Expecting end of text. :
a AND b AND c
^
start
What I understand at this point is that first character of rule matches symbol and not condition "AND" symbol, so grako would like to use it. But my start rule forces that all characters have been consumed.
I've tried to use many workarounds yet but I've not been able to find one that fits.
Grako is in fact a PEG parser. Those parsers have the implicit property of not being able to handle left recursion easily.
More details here and there.
For my needs, I have been able to solve my problem with this kind of expressions :
condition = symbol { "AND" symbol }* ;

Understanding grep with fixed = T in R

I checked different posts on this, but still couldn't figure out why this is not working:
c=c("HI","NO","YESS")
grep("YES",c,fixed=T)
[1] 3
If I am using fixed = T, why I am still getting a results when there is no exact match for "YES". I want only exact matches like when I use grep -w in bash.
This just means that you're matching a string rather than a regular expression, but the string can still be a substring. If you want to match exact cases only, how about
> x=c("HI","NO","YESS") #better not to name variables after common functions
> grep("^YES$",x,fixed=F)
integer(0)
Edit per #nicola: This works b/c ^ means beginning and $ end of string, so ^xxxx$ forces the entire string to match xxxx.

unix shell script : How can I get just the number from the variable contain numbers and characters?

How can I get just the number from the variable contain numbers and characters??
for example:
card=3Hearts
How can I get just the number (3) from the variable $card ?
It's slight overkill for this particular problem, but expr is very powerful this sort of matching problem:
expr $card : '[^0-9]*\([0-9]*\)'
and if you want to get that into another variable:
t=`expr $card : '[^0-9]*\([0-9]*\)'`
The expr command can do a variety of things, but this colon operator – which matches the first argument against a regular expression – has lots of uses.
echo 3Hart | tr -d "[[a-zA-Z]]"

How can I prevent SQLite from treating a string as a number?

I would like to query an SQLite table that contains directory paths to find all the paths under some hierarchy. Here's an example of the contents of the column:
/alpha/papa/
/alpha/papa/tango/
/alpha/quebec/
/bravo/papa/
/bravo/papa/uniform/
/charlie/quebec/tango/
If I search for everything under /bravo/papa/, I would like to get:
/bravo/papa/
/bravo/papa/uniform/
I am currently trying to do this like so (see below for the long story of why I can't use more simple methods):
SELECT * FROM Files WHERE Path >= '/bravo/papa/' AND Path < '/bravo/papa0';
This works. It looks a bit weird, but it works for this example. '0' is the unicode code point 1 greater than '/'. When ordered lexicographically, all the paths starting with '/bravo/papa/' compare greater than it and less than 'bravo/papa0'. However, in my tests, I find that this breaks down when we try this:
SELECT * FROM Files WHERE Path >= '/' AND Path < '0';
This returns no results, but it should return every row. As far as I can tell, the problem is that SQLite is treating '0' as a number, not a string. If I use '0Z' instead of '0', for example, I do get results, but I introduce a risk of getting false positives. (For example, if there actually was an entry '0'.)
The simple version of my question is: is there some way to get SQLite to treat '0' in such a query as the length-1 string containing the unicode character '0' (which should sort strings such as '!', '*' and '/', but before '1', '=' and 'A') instead of the integer 0 (which SQLite sorts before all strings)?
I think in this case I can actually get away with special-casing a search for everything under '/', since all my entries will always start with '/', but I'd really like to know how to avoid this sort of thing in general, as it's unpleasantly surprising in all the same ways as Javascript's "==" operator.
First approach
A more natural approach would be to use the LIKE or GLOB operator. For example:
SELECT * FROM Files WHERE Path LIKE #prefix || '%';
But I want to support all valid path characters, so I would need to use ESCAPE for the '_' and '%' symbols. Apparently this prevents SQLite from using an index on Path. (See http://www.sqlite.org/optoverview.html#like_opt ) I really want to be able to benefit from an index here, and it sounds like that's impossible using either LIKE or GLOB unless I can guarantee that none of their special characters will occur in the directory name, and POSIX allows anything other than NUL and '/', even GLOB's '*' and '?' characters.
I'm providing this for context. I'm interested in other approaches to solve the underlying problem, but I'd prefer to accept an answer that directly addresses the ambiguity of strings-that-look-like-numbers in SQLite.
Similar questions
How do I prevent sqlite from evaluating a string as a math expression?
In that question, the values weren't quoted. I get these results even when the values are quoted or passed in as parameters.
EDIT - See my answer below. The column was created with the invalid type "STRING", which SQLite treated as NUMERIC.
* Groan *. The column had NUMERIC affinity because it had accidentally been specified as "STRING" instead of "TEXT". Since SQLite didn't recognize the type name, it made it NUMERIC, and because SQLite doesn't enforce column types, everything else worked as expected, except that any time a number-like string is inserted into that column it is converted into a numeric type.

Resources