Why does my script fail to create zip files? - zip

#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.

Related

Command not found in tcsh

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.

"Attempted assignment to a non-variable" in bash

I'm new to Bash and I've been having issues with creating a script. What this script does is take numbers and add them to a total. However, I can't get total to work.It constantly claims that total is a non-variable despite it being assigned earlier in the program.
error message (8 is an example number being entered)
./adder: line 16: 0 = 0 + 8: attempted assignment to non-variable (error token is "= 0 + 8")
#!/bin/bash
clear
total=0
count=0
while [[ $choice != 0 ]]; do
echo Please enter a number or 0 to quit
read choice
if [[ $choice != 0 ]];
then
$(($total = $total + $choice))
$(($count = $count + 1))
echo Total is $total
echo
echo Total is derived from $count numbers
fi
done
exit 0
Get rid of some of the dollar signs in front of the variable names. They're optional inside of an arithmetic context, which is what ((...)) is. On the left-hand side of an assignment they're not just optional, they're forbidden, because = needs the variable name on the left rather than its value.
Also $((...)) should be plain ((...)) without the leading dollar sign. The dollar sign will capture the result of the expression and try to run it as a command. It'll try to run a command named 0 or 5 or whatever the computed value is.
You can write:
((total = $total + $choice))
((count = $count + 1))
or:
((total = total + choice))
((count = count + 1))
or even:
((total += choice))
((count += 1))

Shell for loop, stopping at declaration

I'm trying to write a for loop that goes from 1 to 10, then calculates ( 1 through 10 mod 5) + 2. After that I want to display it like this (1 to 10 mod 5) + 2 = answer. However i'm getting an error at the beginning of the loop which is a syntax error.
for (( i = 0; i <= 10; i++)); do
calculate=(i % 5) + 2
echo ("("i "% 5) + 2" calculate)
done
Try these changes:
calculate=$(( i % 5 + 2 ))
# $(( ... )) is the shell's way to do arithmetic
echo "($i % 5) + 2 = " $calculate
# $x is a way to refer to the value of variable x
# (also inside a double-quoted string)
The for loop header is actually OK.

perl index skips search value

I am writing a program that is heavily dependent on the perl's index function to take strings. My objective so to break this string into a series of substrings that do not have any spaces.
The problem that I am having is that in the second half of the loop the index function starts skipping spaces.
I am using the test data:
1 12 a 2 5 P Q
I am expecting to get:
1, 12, a, 2, 5, P, Q,
Instead I get:
1, 12, a, 2 5, P Q,
My code follows:
use 5.010;
use strict;
use warnings;
my $ivalue = <stdin>;
chomp($ivalue);
$ivalue = $ivalue . " ";
my $current;
my $space = 0;
my $safespace = 0;
my $lastspace = 0;
my $closestspace = 0;
my $i = 0;
# Test data - 1 12 a 2 5 P Q
while ($space != -1){
$space = index($ivalue, " ", $space + $i++);
$closestspace = $space - $lastspace;
#print $lastspace . " " . $space . " = " . $closestspace . "; ";
$current = substr($ivalue, $lastspace, $closestspace);
#say "substring = " . $current;
$lastspace = $space + 1;
}
Thanks ahead of time! If anyone has any suggestion on how to improve the way I asked my question or on my code in general those are appreciated as well.
The problem is in this line:
$space = index($ivalue, " ", $space + $i++);
instead of using $i, make that $space + 1

Variable in a string

I have the following script, but no success executing it without errors. I want to put a variable into a URL and ping that URL.
#include <Excel.au3>
$sFilePath1 = "D:\Desktop\1.xlsx"
$oExcel = _ExcelBookOpen($sFilePath1, 0)
For $i = 1 To 2 ; Loop
Local $username = _ExcelReadcell($oExcel, $i, 1) ;Reading created Excel
Local $iPing = Ping("http://blogsearch.google.co.in/ping?url="$username"&btnG=Submit+Blog&hl=en", 2500)
If $iPing Then ; If a value greater than 0 was returned then display the following message.
MsgBox(0, "STATUS", "Ping Successful", 1)
Else
MsgBox(0, "STATUS", "ERROR", 1)
EndIf
Next
As Teifun2 showed, you just need to write your text between quotes or dual quotes, and then put "&" between the last quote ad the variable, this way :
"I am writing this between double quotes at line # " & $i_Nbr & ' with simple quotes!'
Like Xenobiologist already said in comments to the question, this should just work fine:
#include <Excel.au3>
$sFilePath1 = "D:\Desktop\1.xlsx"
$oExcel = _ExcelBookOpen($sFilePath1, 0)
For $i = 1 To 2 ;Loop
Local $username = _ExcelReadcell($oExcel, $i, 1) ;Reading created Excel
Local $iPing = Ping("http://blogsearch.google.co.in/ping?url="&$username&"&btnG=Submit+Blog&hl=en", 2500)
If $iPing Then ; If a value greater than 0 was returned then display the following message.
MsgBox(0, "STATUS", "Ping Successful" ,1)
Else
MsgBox(0, "STATUS", "ERROR" ,1)
EndIf
Next
You can concatenate the variable to the string
$id = 21622809
MsgBox(0, '', "http://example.com/user/" & $id & "/blah_blah_blah")
or enable the ExpandVarStrings option and use the variable
$id = 21622809
Opt("ExpandVarStrings", 1)
MsgBox(0, "", "http://example.com/user/$id$/blah_blah_blah")

Resources