I wrote a script in groovy to find files java test files recursively in a given directory with certain names, the concerned part of the code is:
def projectRootDirectory = args.length ? new File(args[0]) : new File(System.getProperty("user.dir"))
def srcFilesCount = 0, testFilesCount = 0, srcLinesCount=0, testLinesCount=0
def srcFileSubstringPattern = '.java'
def testFileSubstringPattern = 'Test.java'
projectRootDirectory.eachDirRecurse() { dir ->
dir.eachFile {
if (it.name.endsWith(testFileSubstringPattern) || it.name ==~ /Test.*java/ ||
it.name.endsWith('Tests.java') || it.name.endsWith('TestCase.java')) {
//println "Test file found: " + it.name
testFilesCount++
it.eachLine { testLinesCount++ }
} else if (it.name.contains(srcFileSubstringPattern)) {
srcFilesCount++
it.eachLine { srcLinesCount++ }
}
}
}
It finds already existing files in the repo which was cloned using SVN that match for example someTestCase.java, but when I created some new ones by using the command touch dummyTestCase.java via Cygwin in Windows 7 or via the Windows 7 explorer right click -> New -> Text Document option and rename it to something like TestDummy.java, it doesn't find them. The script also treats copies of the respective files the same way i.e. it finds copies of old files that already existed but not the new ones I create. I even opened up file permissions to fullest on the newly created files, but no change. Whereas the BASH find command via Cygwin always finds all the files without any issue. I have confirmed using diagnostic print statements the the script is looking in the correct directory. I even confirmed this by having the script create some files there and confirmed they got created in the correct place.
Wow, the answer turned out to be amazingly simple. I replaced eachDirRecurse with eachFileRecurse thus also eliminating the nested loop. Thanks a ton to all the comment authors whose help led me to this discovery.
Related
lets say I have an array with directory names
dirs = ['opt', 'apps', 'apache']
I want to iterate and generate a list of following paths
/opt
/opt/apps
/opt/apps/apache
through which I can create file resource.
Is there a reason you want to iterate through those files like that?
Because the simplest way to turn those into file resources would be this:
$dirs = ['/opt', '/opt/apps', '/opt/apps/apache']
file { $dirs:
ensure => directory,
}
If you just want to make sure that all the preceeding directories are created, there is also the dirtree module, which will do this all for you:
https://forge.puppet.com/pltraining/dirtree
$apache_dir = dirtree('/opt/apps/apache')
# Will return: ['/opt', '/opt/apps', '/opt/apps/apache']
You can then use that variable to create the directories.
As Matt mentions, you can also use maps, or an iterator to create the resources.
Basic example here:
$dirs = ['/opt', '/opt/apps', '/opt/apps/apache']
$dirs.each |String $path| {
file {$path:
ensure => directory,
}
}
Documented here: https://docs.puppet.com/puppet/latest/lang_iteration.html
There are a few different ways to do what you want to do in the code, it depends on how much management you want to do of those resources after creation.
This is similar to A copy of Excel Addin is created in My Documents after saving, except that I'm working with Perl instead of VBA, and xls files instead of xlsm, and the negative impact of the behavior is different.
I've inherited a Perl script (Perl 5.8.8) that is running on Windows 2003 Server as SYSTEM. After copying an Excel 2003 template file to a unique, fully defined path location, it opens the unique file in Excel using OLE, edits the file, saves the file, and closes the file. What results is the edited file being saved both in the correct, fully-defined path location, and also in the Default User profile's Documents folder.
This causes thousands of these files to accumulate on the C: drive, as every new admin to be hired gets a copy in his Documents folder.
Adding the code that sets the value of $OUT:
if (!$db->Sql("EXEC GetDetails 'name'"))
{
while ($db->FetchRow()>0)
{
#DataIn = $db->Data();
$name = $DataIn[0];
$IN = $DataIn[1];
$OUT = $DataIn[2];
opendir(DIR,"$OUT") || die "$OUT directory does not exist $!\n";
#... loop of proprietary code
#...
#Completed = $db1->Data();
#...
&formatExcelReport #The code that I previously posted
#...
# more proprietary code
# end of loop
} #end of while
}#end of if
The code I originally posted:
# Initialize Excel object
eval {Win32::OLE->new('Excel.Application', 'Quit')};
eval {$Excel = Win32::OLE->GetActiveObject('Excel.Application')};
unless (defined $Excel)
{
$Excel = Win32::OLE->GetActiveObject('Excel.Application')
|| Win32::OLE->new('Excel.Application', 'Quit');
}
$infiles = "Report_Template.xls";
$infiles = $OUT."/".$infiles;
$db6->Sql("EXEC FormatResults '".$Completed[0]."','".$Completed[1]."'");
$row = 2;
$fileName = $Completed[0]."_".$Completed[1];
$uniquefile = $fileName.$printdate.".xls";
# $OUT is a fully defined path on the E: drive
$reportfile = "$OUT"."\\".$uniquefile;
copy($infiles,$reportfile);
$Book = $Excel->Workbooks->Open("$reportfile");
$sheetnum = 1;
my $Sheet = $Book->Worksheets($sheetnum);
# Set Headers
$Header = $Sheet->PageSetup->{'CenterHeader'};
$Header = $Header." Results Test Code: ".$Completed[0]." Worksheet: ".$Completed[1]." Date: ".$headerdate;
$Sheet->PageSetup->{'CenterHeader'}= $Header;
# More file editing
# ...
$Book->Save();
$Book->Close(0);
Win32::OLE->new('Excel.Application', 'Quit');
Is the root of this problem the Save() command? Should I be using SaveAs() instead?
Any other feedback about how Excel is being used welcome, as well.
Thanks!
I don't see what causes this behavior, but here are a few things to try.
The template and the file it is copied to have names
$infiles = $OUT."/".$infiles;
$reportfile = "$OUT"."\\".$uniquefile;
Use the same separator.
Try to suppress some possible setting dictating that another copy be made. Perhaphs
$Excel->Application->{CreateBackup} = 0;
However, this may not be the correct property -- search the VB or Excel documentation for properties that may result in Excel saving an extra copy. (It needn't be "backup".)
Try to create a new file and use SaveAs, as a test to see whether you get two files again. The template copying may be setting it off to Save an extra copy (even though I don't see how). I'd say it's either that, or some general setting that need be turned off.
The rest is the original post, about using SaveAs, whereby I thought that a new file is created
You would use SaveAs to write a new file. See saveas in MSDN library
Saves changes to the workbook in a different file.
Using the save method may result in saving two files fro some reason, as noted in the answer by Borodin. This page also advises to use SaveAs for a new file
The first time you save a workbook, use the SaveAs method to specify a name for the file.
Once you change to using SaveAs there should be a confirmation dialog to deal with. If you want to suppress that you can set a property, with one (or either?) of
$Excel->Application->{DisplayAlerts} = 0;
# or
$Excel->{DisplayAlerts} = 0;
For a number of options, including backups for example, see the Chapter on OLE automation in PERL in a Nutshell.
A note on some other resources. There is a cookbook of sorts in this post on perlmonks. A listing of various operations is given in this SO post.
Finally, I don't know how deep the reasons for using OLE are but if it is only about writing some Excel files there are other modules. For example the very well regarded Spreadsheet::WriteExcel and Excel-Writer-XLSX.
That's very strange Perl code. eval without checking $# afterwards is just wrong -- you need to know if a step of your code has failed for the following steps to make sense
It looks like the problem is in your call to copy($infiles, $reportfile). That will save one copy of the file, while $Book->Save and $Book->Close will save another
currently, what happens in windows explorer when highlighting and batch renaming files/folders is as such:
test(1).jpg
test(2).jpg
test(3).jpg
how do i code a script such that highlighting the files/folders and hitting the same hotkey (f2) allows me to change the naming convention?
Variable {space} ###.jpg
where Variable is the name for user input and ### is the running sequence starting from 001?
in addition, i need the script to IGNORE warnings when there's already another file with the previous same name. one possible way to overcome this is to temporarily rename the offending file to a temp name first, so that the renamer can continue with its correct sequence.
Yes, i do know there are many capable applications that can already do the simple job above - but i prefer NOT to have a GUI (since it's v simple).
appreciate everyone's help!
consider this example :
#Include Explorer.ahk ;get it from : https://github.com/denolfe/AutoHotkey/blob/master/lib/Explorer.ahk
F2::
InputBox, Variable, Rename files, Enter your filename prefix.,, 250, 150,,,,,DefaultPrefix
path := Explorer_GetPath()
sel := Explorer_GetSelected()
MsgBox % sel
if ( StrLen(sel) && FileExist(path) )
{
Loop, Parse, sel, `n
{
SetWorkingDir, %path%
MsgBox %A_loopfield%
FileMove, %A_loopfield%, %Variable%_%A_index%.*, 1 ; the '1' means Overwrite
}
}
return
I am having a bit of trouble getting my groovy code to work properly in Jenkins using the Dynamic choice parameter. We currently have a folder that contains a lot of properties files for various environments. The following groovy code returns a list of all the file names correctly, however it is appending the file extension which is unneeded.
Arrays.asList(new File("path").list())
How would I change that to only list .xml files and not append the file extension in the list. I've found some examples of this while searching, but for some reason when I try some of these examples it isn't populating the list.
You mean like:
new File( 'path' ).list()
.findAll { it.endsWith( '.xml' ) }
.collect { it[ 0..-5 ] }
That gets the list of files (as Strings), keeps those that end with .xml, then removes the .xml off the end
I'm trying to check if a folder has any subfolders without iterating through its children, in Linux. The closest I've found so far is using ftw and stopping at the first subfolder - or using scandir and filtering through the results. Both, are, however, an overkill for my purposes, I simply want a yes/no.
On Windows, this is done by calling SHGetFileInfo and then testing dwAttributes & SFGAO_HASSUBFOLDER on the returned structure. Is there such an option on Linux?
The standard answer is to call stat on the directory, then check the st_nlink field ("number of hard links"). On a standard filesystem, each directory is guaranteed to have 2 hard links (. and the link from the parent directory to the current directory), so each hard link beyond 2 indicates a subdirectory (specifically, the subdirectory's .. link to the current directory).
However, it's my understanding that filesystems aren't required to implement this (see, e.g., this mailing list posting), so it's not guaranteed to work.
Otherwise, you have to do as you're doing:
Iterate over the directory's contents using glob with the GNU-specific GLOB_ONLYDIR flag, or scandir, or readdir.
Call stat on each result and check S_ISDIR(s.st_mode) to verify that files found are directories. Or, nonportably, check struct dirent.d_type: if it's DT_DIR then it's a file, and if it's DT_UNKNOWN, you'll have to stat it after all.
The possibilities you've mentioned (as well as e.James's) seem to me like they're better suited to a shell script than a C++ program. Presuming the "C++" tag was intentional, I think you'd probably be better off using the POSIX API directly:
// warning: untested code.
bool has_subdir(char const *dir) {
std::string dot("."), dotdot("..");
bool found_subdir = false;
DIR *directory;
if (NULL == (directory = opendir(dir)))
return false;
struct dirent *entry;
while (!found_subdir && ((entry = readdir(directory)) != NULL)) {
if (entry->d_name != dot && entry->d_name != dotdot) {
struct stat status;
stat(entry->d_name, &status);
found_subdir = S_ISDIR(status.st_mode);
}
}
closedir(directory);
return found_subdir;
}
Does getdirentries do want you want it to do? I think it shoudl return nothing if there are no directories. I would have tried this myself but am temporarily without access to a linux box :(