Command not found in tcsh - linux

I have trouble with this code. Are my assigns properly done? I gave "q: Command not found.Badly placed ()'s."
#!/bin/tcsh
set h = 0
set q = 0
set a = 0
foreach val ( $* )
if ($val == "-h")then
h = 1
endif
if ($val == "-q")then
q = 1
endif
if ($val != "-h") && ($val != "-q")then
a = 1
endif
end

Building on the comments about the ()s and spaces, here is a version that works:
#!/bin/tcsh
set h = 0
set q = 0
set a = 0
foreach val ( $* )
if ($val == "-h") then
set h = 1
endif
if ($val == "-q") then
set q = 1
endif
if ($val != "-h" && $val != "-q") then
set a = 1
endif
end
Added spaces after )s
Put && within the ()s
Use set to set variables. Bourne shell just has x=y but *csh requires set x=y.
You might also want to look into getopt -- if you have a Linux or GNU version of that command available, it can make option parsing a lot more standardized.

Related

Keep receiving "Else: endif not found." error

This is the prompt for my script:
Script that asks the user “Are you OK?”
If user replies y or Y, then say “glad to hear it” else if the user enters n or N then print “sorry that you are not feeling good”. If the user enters some other character, then print in-correct choice and ask the question again.
Here's what I have:
#! /bin/csh
echo "Are you OK? "
set n = $<
set loop = 1
if (("$n" == "y") || ("$n" == "Y")) then
echo "glad to hear it"
else if (("$n" == "n") || ("$n" == "N")) then
echo "sorry that you are not feeling good"
else
echo "in-correct choice"
while ( $loop == 1 )
echo "Are you OK? "
set n = $<
if (("$n" == "y") || ("$n" == "Y")) then
echo "glad to hear it"
set loop = 0
else if (("$n" == "n") || ("$n" == "N")) then
echo "sorry that you are not feeling good"
set loop = 0
else
echo "in-correct choice"
endif
end
endif
I keep receiving the error "else: endif not found." Also the echo line "glad to hear it" runs every time regardless if the user input is right or not. Please help. Thank you
Just add new line after Your last endif statement:
...
end
endif
#new line
Or I recommend always end csh scripts with exit status and You should be good to go:
...
end
endif
exit (0)
Anyway here is also little rewrite of Your script:
#!/bin/env csh
while (1)
echo "Are you OK?"
set n = "$<"
if (("$n" == "y") || ("$n" == "Y")) then
echo "glad to hear it"
break
else if (("$n" == "n") || ("$n" == "N")) then
echo "sorry that you are not feeling good"
break
else
echo "in-correct choice"
endif
end
exit (0)
set n = $< here is danger better set n = "$<" in order not to handle e.g. string y abc as yes

Shell script, stop running if failed

I have a shell script that runs a test repeatedly :
#!/bin/tcsh
set x = 1
while ($x <= 10000)
echo $x
./test
# x += 1
end
I am trying to adapt it to break the loop and stop running if the test failed, i.e. the test executable returned with a non-zero status. I thought the following change would work.
#!/bin/tcsh
set x = 1
set y = 0
while ($x <= 10000 && $y == 0)
echo $x
# y = ./test
# x += 1
end
But, I get error #: Expression syntax
Can you please tell me what did I do wrong, and how to capture the return value of ./test in a variable so I can break the loop, or some other way to break the loop upon encountering the test failure
I'm not a fan of scripting in csh, and I highly advise against it. However, in this case, csh seems to do the right thing, and you can simply do:
#!/bin/tcsh
set x = 1
while ($x <= 10000)
echo $x
./test || break
# x += 1
end

Vimscript all matches

I'm new to Vimscript but I am trying to find all the lines which contain #property.
What I am trying is:
norm! gg
wh search( "#property", "cW" ) != 0
echo getline( "." )
endw
But this code has a deadlock. What am I doing wrong?
Don’t pass the c flag, or at least not every time. c specifies that a match at the cursor should be accepted – but search() always moves the cursor to a match!
For example,
let flags = "cW"
while search("#property", flags) != 0
echo getline(".")
let flags = "W"
endwhile

possibility of using a function to calculate sum in vim

I have some parameters in a text file which goes as follows
parameter1 =5
parameter2=4
----------
---------
parameter(n-1) = 6
parameter(n)=11
My requirement is that the values of the parameters should sum upto 100 and there can be number of parameters. I was wondering if I could write a function in Vim , which could calculate the sum and display it somewhere?
I have no idea how to pass arguement to such a function,I was thinking it could somehow be done by block selecting the lines with parameter values.
Add following function to your vimrc file:
function! CustomSum()
let sum = 0
for l in range( 1, line('$') )
let fields = split( getline(l), '\s*=\s*' )
if ( len( fields ) != 2 || fields[1] =~? '\D' )
continue
endif
let sum = sum + fields[1]
endfor
return sum
endfunction
And run it:
:echo CustomSum()
That with your input data yields:
26
EDIT to add a range to previous function. Now accepts a range as input parameters named a:firstline and a:lastline. I increment them with 0 to convert them to integers, otherwise the range function complains. Last line echoes the result for debugging but would be better idea to handle the result in a return call (only uncomment it).
function! CustomSum() range
let sum = 0
for l in range( a:firstline + 0, a:lastline + 0 )
let fields = split( getline(l), '\s*=\s*' )
if ( len( fields ) != 2 || fields[1] =~? '\D' )
continue
endif
let sum = sum + fields[1]
endfor
echo sum
"" return sum
endfunction
Now you can do visually selection or normal ranges, like:
:'<,'>call CustomSum()
or
:1,5call CustomSum()
Both should work.
This can also be done with a (pseudo) one-liner as well:
:let s=0
:g/parameter\d\+\s*=\s*\d\+/let s+=matchstr(getline('.'), '\d\+\s*$')
:echo s
It you want a function you fall back to Birei's solution
EDIT: BTW, we can also echo it directly with:
echo eval(join(map(filter(getline(1,'$'), 'v:val =~ "=\\s*\\d"'), 'matchstr(v:val, "=\\s*\\zs\\d\\+")'), '+'))
or if you prefer a command:
command! -nargs=0 -range=% Sum echo eval(join(map(filter(getline(<line1>,<line2>), 'v:val =~ "=\\s*\\d"'), 'matchstr(v:val, "=\\s*\\zs\\d\\+")'), '+'))

Why does my script fail to create zip files?

#include <File.au3>
#include <Zip.au3>
#include <Array.au3>
; bad file extensions
Local $extData = "ade|adp|app|asa|ashx|asp|bas|bat|cdx|cer|chm|class|cmd|com|cpl|crt|csh|der|exe|fxp|gadget|hlp|hta|htr|htw|ida|idc|idq|ins|isp|its|jse|ksh|lnk|mad|maf|mag|mam|maq|mar|mas|mat|mau|mav|maw|mda|mdb|mde|mdt|mdw|mdz|msc|msh|msh1|msh1xml|msh2|msh2xml|mshxml|msi|msp|mst|ops|pcd|pif|prf|prg|printer|pst|reg|rem|scf|scr|sct|shb|shs|shtm|shtml|soap|stm|url|vb|vbe|vbs|ws|wsc|wsf|wsh"
Local $extensions = StringSplit($extData, "|")
; What is the root directory?
$rootDirectory = InputBox("Root Directory", "Please enter the root directory...")
archiveDir($rootDirectory)
Func archiveDir($dir)
$goDirs = True
$goFiles = True
; Get all the files under the current dir
$allOfDir = _FileListToArray($dir)
$tmax = UBound($allOfDir)
For $t = 0 To $tmax - 1
Next
Local $countDirs = 0
Local $countFiles = 0
$imax = UBound($allOfDir)
For $i = 0 To $imax - 1
If StringInStr(FileGetAttrib($dir & "\" & $allOfDir[$i]), "D") Then
$countDirs = $countDirs + 1
ElseIf StringInStr(($allOfDir[$i]), ".") Then
$countFiles = $countFiles + 1
EndIf
Next
If ($countDirs > 0) Then
Local $allDirs[$countDirs]
$goDirs = True
Else
$goDirs = False
EndIf
If ($countFiles > 0) Then
Local $allFiles[$countFiles]
$goFiles = True
Else
$goFiles = False
EndIf
$dirCount = 0
$fileCount = 0
For $i = 0 To $imax - 1
If (StringInStr(FileGetAttrib($dir & "\" & $allOfDir[$i]), "D")) And ($goDirs == True) Then
$allDirs[$dirCount] = $allOfDir[$i]
$dirCount = $dirCount + 1
ElseIf (StringInStr(($allOfDir[$i]), ".")) And ($goFiles == True) Then
$allFiles[$fileCount] = $allOfDir[$i]
$fileCount = $fileCount + 1
EndIf
Next
; Zip them if need be in current spot using 'ext_zip.zip' as file name, loop through each file ext.
If ($goFiles == True) Then
$fmax = UBound($allFiles)
For $f = 0 To $fmax - 1
$currentExt = getExt($allFiles[$f])
$position = _ArraySearch($extensions, $currentExt)
If #error Then
MsgBox(0, "Not Found", "Not Found")
Else
$zip = _Zip_Create($dir & "\" & $currentExt & "_zip.zip")
_Zip_AddFile($zip, $dir & "\" & $allFiles[$f])
EndIf
Next
EndIf
; Get all dirs under current DirCopy
; For each dir, recursive call from step 2
If ($goDirs == True) Then
$dmax = UBound($allDirs)
$rootDirectory = $rootDirectory & "\"
For $d = 0 To $dmax - 1
archiveDir($rootDirectory & $allDirs[$d])
Next
EndIf
EndFunc
Func getExt($filename)
$pos = StringInStr($filename, ".")
$retval = StringTrimLeft($filename, $pos - 1)
Return $retval
EndFunc
I have a list of file extensions. This script should go through a directory (and subdirectories), zip up (separate zip files for each extension) all files with those extensions.
Why does it not create zip files?
In the function StringTrimLeft("string", count), count is the number of characters to trim.
$filename = "filename.zip"
$pos = StringInStr($filename, ".") ; $pos will be equal to 9
so...
$retval = StringTrimLeft($filename, $pos + 1); this will remove 10 characters = ip
Two suggestions:
Add MsgBox(0, "Zip", "Got here") inside your If ($currentExt == $extensions[$e]) Then. You should see that you are never getting there.
Related to the above, your getExt function is not returning the correct value for the extension of the file.
UPDATE
You went a little too far with your edit to getExt.
Try this:
Func getExt($filename)
$pos = StringInStr($filename, ".")
$retval = StringTrimLeft($filename, $pos)
Return $retval
EndFunc
UPDATE 2
Regarding your problem where it doesn't process folders beyond the 2nd level, your issue is you are using $rootDirectory in your recursive call where you need to use $dir.
Change the last part of your archiveDir function to this:
; For each dir, recursive call from step 2
If ($goDirs == True) Then
$dmax = UBound($allDirs)
$dir = $dir & "\"
For $d = 0 to $dmax - 1
archiveDir($dir & $allDirs[$d])
Next
EndIf
I tried running your code as is, and sure enough, it failed. I then put a
MsgBox(0, "error", #error & " " & $currentExt)
in the "If #error" block to see if I could find out why it was failing. The result was the #error came back as 6. Looking into the documentation, it says that an error code of 6 means that the value searched for was not found in the array. And then the $currentExt told me it's value was set to ".asp".
The reason it could not be found was because there are no periods in the extension names in the array. If you look closer at the getExt() function, before you were adding 1 to the $position value... and now you are subtracting 1 from the value... Here's an illustration of how StringTrimLeft() works...
$filename = "filename.txt"
$pos = StringInStr($filename, ".") ; $pos will be equal to 9
$retval = StringTrimLeft($filename, $pos + 1); this will remove 10 characters = xt, that's too much.
$retval = StringTrimLeft($filename, $pos - 1); this will remove 8 characters = .txt, that's not enough.
$retval = StringTrimLeft($filename, $pos); this will remove 9 characters = txt, that's juuuuuuust right!
So the solution is to either add "." in front of all of the extensions in your array, or change your getExt() function:
Func getExt($filename)
$pos = StringInStr($filename, ".")
$retval = StringTrimLeft($filename, $pos)
Return $retval
EndFunc
There is one more option you could look into, and that is using the _PathSplit() function found in File.au3, but since your script is so close to working at this point, I wouldn't worry about it, but maybe in the future you could use it instead.
And one last note... After I changed getExt() to drop the ".", your script ran great.

Resources